diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/DistributedOpenstackRouterStore.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/DistributedOpenstackRouterStore.java
new file mode 100644
index 0000000..6b10512
--- /dev/null
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/DistributedOpenstackRouterStore.java
@@ -0,0 +1,423 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstacknetworking.impl;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableSet;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.openstacknetworking.api.OpenstackRouterEvent;
+import org.onosproject.openstacknetworking.api.OpenstackRouterStore;
+import org.onosproject.openstacknetworking.api.OpenstackRouterStoreDelegate;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.Versioned;
+import org.openstack4j.model.network.ExternalGateway;
+import org.openstack4j.model.network.NetFloatingIP;
+import org.openstack4j.model.network.Router;
+import org.openstack4j.model.network.RouterInterface;
+import org.openstack4j.model.network.State;
+import org.openstack4j.openstack.networking.domain.NeutronExternalGateway;
+import org.openstack4j.openstack.networking.domain.NeutronFloatingIP;
+import org.openstack4j.openstack.networking.domain.NeutronHostRoute;
+import org.openstack4j.openstack.networking.domain.NeutronRouter;
+import org.openstack4j.openstack.networking.domain.NeutronRouterInterface;
+import org.osgi.service.component.annotations.Activate;
+import org.slf4j.Logger;
+
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
+import static org.onosproject.openstacknetworking.api.OpenstackRouterEvent.Type.*;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Manages the inventory of OpenStack router and floating IP using a {@code ConsistentMap}.
+ */
+@Service
+@Component(immediate = true)
+public class DistributedOpenstackRouterStore
+        extends AbstractStore<OpenstackRouterEvent, OpenstackRouterStoreDelegate>
+        implements OpenstackRouterStore {
+
+    protected final Logger log = getLogger(getClass());
+
+    private static final String ERR_NOT_FOUND = " does not exist";
+    private static final String ERR_DUPLICATE = " already exists";
+
+    private static final KryoNamespace SERIALIZER_NEUTRON_L3 = KryoNamespace.newBuilder()
+            .register(KryoNamespaces.API)
+            .register(Router.class)
+            .register(NeutronRouter.class)
+            .register(State.class)
+            .register(NeutronHostRoute.class)
+            .register(ExternalGateway.class)
+            .register(NeutronExternalGateway.class)
+            .register(RouterInterface.class)
+            .register(NeutronRouterInterface.class)
+            .register(NetFloatingIP.class)
+            .register(NeutronFloatingIP.class)
+            .build();
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    private final ExecutorService eventExecutor = newSingleThreadExecutor(
+            groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
+    private final MapEventListener<String, Router> routerMapListener = new OpenstackRouterMapListener();
+    private final MapEventListener<String, RouterInterface> routerInterfaceMapListener =
+            new OpenstackRouterInterfaceMapListener();
+    private final MapEventListener<String, NetFloatingIP> floatingIpMapListener =
+            new OpenstackFloatingIpMapListener();
+
+    private ConsistentMap<String, Router> osRouterStore;
+    private ConsistentMap<String, RouterInterface> osRouterInterfaceStore;
+    private ConsistentMap<String, NetFloatingIP> osFloatingIpStore;
+
+    @Activate
+    protected void activate() {
+        ApplicationId appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
+
+        osRouterStore = storageService.<String, Router>consistentMapBuilder()
+                .withSerializer(Serializer.using(SERIALIZER_NEUTRON_L3))
+                .withName("openstack-routerstore")
+                .withApplicationId(appId)
+                .build();
+        osRouterStore.addListener(routerMapListener);
+
+        osRouterInterfaceStore = storageService.<String, RouterInterface>consistentMapBuilder()
+                .withSerializer(Serializer.using(SERIALIZER_NEUTRON_L3))
+                .withName("openstack-routerifacestore")
+                .withApplicationId(appId)
+                .build();
+        osRouterInterfaceStore.addListener(routerInterfaceMapListener);
+
+        osFloatingIpStore = storageService.<String, NetFloatingIP>consistentMapBuilder()
+                .withSerializer(Serializer.using(SERIALIZER_NEUTRON_L3))
+                .withName("openstack-floatingipstore")
+                .withApplicationId(appId)
+                .build();
+        osFloatingIpStore.addListener(floatingIpMapListener);
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        osRouterStore.removeListener(routerMapListener);
+        osRouterInterfaceStore.removeListener(routerInterfaceMapListener);
+        osFloatingIpStore.removeListener(floatingIpMapListener);
+        eventExecutor.shutdown();
+
+        log.info("Stopped");
+    }
+
+    @Override
+    public void createRouter(Router osRouter) {
+        osRouterStore.compute(osRouter.getId(), (id, existing) -> {
+            final String error = osRouter.getName() + ERR_DUPLICATE;
+            checkArgument(existing == null, error);
+            return osRouter;
+        });
+    }
+
+    @Override
+    public void updateRouter(Router osRouter) {
+        osRouterStore.compute(osRouter.getId(), (id, existing) -> {
+            final String error = osRouter.getName() + ERR_NOT_FOUND;
+            checkArgument(existing != null, error);
+            return osRouter;
+        });
+    }
+
+    @Override
+    public Router removeRouter(String routerId) {
+        Versioned<Router> osRouter = osRouterStore.remove(routerId);
+        return osRouter == null ? null : osRouter.value();
+    }
+
+    @Override
+    public Router router(String routerId) {
+        Versioned<Router> versioned = osRouterStore.get(routerId);
+        return versioned == null ? null : versioned.value();
+    }
+
+    @Override
+    public Set<Router> routers() {
+        Set<Router> osRouters = osRouterStore.values().stream()
+                .map(Versioned::value)
+                .collect(Collectors.toSet());
+        return ImmutableSet.copyOf(osRouters);
+    }
+
+    @Override
+    public void addRouterInterface(RouterInterface osRouterIface) {
+        osRouterInterfaceStore.compute(osRouterIface.getPortId(), (id, existing) -> {
+            final String error = osRouterIface.getPortId() + ERR_DUPLICATE;
+            checkArgument(existing == null, error);
+            return osRouterIface;
+        });
+    }
+
+    @Override
+    public void updateRouterInterface(RouterInterface osRouterIface) {
+        osRouterInterfaceStore.compute(osRouterIface.getPortId(), (id, existing) -> {
+            final String error = osRouterIface.getPortId() + ERR_NOT_FOUND;
+            checkArgument(existing != null, error);
+            return osRouterIface;
+        });
+    }
+
+    @Override
+    public RouterInterface removeRouterInterface(String routerIfaceId) {
+        Versioned<RouterInterface> osRouterIface = osRouterInterfaceStore.remove(routerIfaceId);
+        return osRouterIface == null ? null : osRouterIface.value();
+    }
+
+    @Override
+    public RouterInterface routerInterface(String routerIfaceId) {
+        Versioned<RouterInterface> osRouterIface = osRouterInterfaceStore.get(routerIfaceId);
+        return osRouterIface == null ? null : osRouterIface.value();
+    }
+
+    @Override
+    public Set<RouterInterface> routerInterfaces() {
+        Set<RouterInterface> osRouterIfaces = osRouterInterfaceStore.values().stream()
+                .map(Versioned::value)
+                .collect(Collectors.toSet());
+        return ImmutableSet.copyOf(osRouterIfaces);
+    }
+
+    @Override
+    public void createFloatingIp(NetFloatingIP osFloatingIp) {
+        osFloatingIpStore.compute(osFloatingIp.getId(), (id, existing) -> {
+            final String error = osFloatingIp.getId() + ERR_DUPLICATE;
+            checkArgument(existing == null, error);
+            return osFloatingIp;
+        });
+    }
+
+    @Override
+    public void updateFloatingIp(NetFloatingIP osFloatingIp) {
+        osFloatingIpStore.compute(osFloatingIp.getId(), (id, existing) -> {
+            final String error = osFloatingIp.getId() + ERR_NOT_FOUND;
+            checkArgument(existing != null, error);
+            return osFloatingIp;
+        });
+    }
+
+    @Override
+    public NetFloatingIP removeFloatingIp(String floatingIpId) {
+        Versioned<NetFloatingIP> osFloatingIp = osFloatingIpStore.remove(floatingIpId);
+        return osFloatingIp == null ? null : osFloatingIp.value();
+    }
+
+    @Override
+    public NetFloatingIP floatingIp(String floatingIpId) {
+        Versioned<NetFloatingIP> osFloatingIp = osFloatingIpStore.get(floatingIpId);
+        return osFloatingIp == null ? null : osFloatingIp.value();
+    }
+
+    @Override
+    public Set<NetFloatingIP> floatingIps() {
+        Set<NetFloatingIP> osFloatingIps = osFloatingIpStore.values().stream()
+                .map(Versioned::value)
+                .collect(Collectors.toSet());
+        return ImmutableSet.copyOf(osFloatingIps);
+    }
+
+    private class OpenstackRouterMapListener implements MapEventListener<String, Router> {
+
+        @Override
+        public void event(MapEvent<String, Router> event) {
+            switch (event.type()) {
+                case UPDATE:
+                    log.debug("OpenStack router updated {}", event.newValue());
+                    eventExecutor.execute(() -> {
+                        notifyDelegate(new OpenstackRouterEvent(
+                                OPENSTACK_ROUTER_UPDATED,
+                                event.newValue().value()));
+                        processGatewayUpdate(event);
+                    });
+                    break;
+                case INSERT:
+                    log.debug("OpenStack router created {}", event.newValue());
+                    eventExecutor.execute(() -> {
+                        notifyDelegate(new OpenstackRouterEvent(
+                                OPENSTACK_ROUTER_CREATED,
+                                event.newValue().value()));
+                    });
+                    break;
+                case REMOVE:
+                    log.debug("OpenStack router removed {}", event.oldValue());
+                    eventExecutor.execute(() -> {
+                        notifyDelegate(new OpenstackRouterEvent(
+                                OPENSTACK_ROUTER_REMOVED,
+                                event.oldValue().value()));
+                    });
+                    break;
+                default:
+                    log.error("Unsupported event type");
+                    break;
+            }
+        }
+
+        private void processGatewayUpdate(MapEvent<String, Router> event) {
+            ExternalGateway oldGateway = event.oldValue().value().getExternalGatewayInfo();
+            ExternalGateway newGateway = event.newValue().value().getExternalGatewayInfo();
+
+            if (oldGateway == null && newGateway != null) {
+                notifyDelegate(new OpenstackRouterEvent(
+                        OPENSTACK_ROUTER_GATEWAY_ADDED,
+                        event.newValue().value(), newGateway));
+            }
+            if (oldGateway != null && newGateway == null) {
+                notifyDelegate(new OpenstackRouterEvent(
+                        OPENSTACK_ROUTER_GATEWAY_ADDED,
+                        event.newValue().value(), oldGateway));
+            }
+        }
+    }
+
+    private class OpenstackRouterInterfaceMapListener implements MapEventListener<String, RouterInterface> {
+
+        @Override
+        public void event(MapEvent<String, RouterInterface> event) {
+            switch (event.type()) {
+                case UPDATE:
+                    log.debug("OpenStack router interface updated {}", event.newValue());
+                    eventExecutor.execute(() -> {
+                        notifyDelegate(new OpenstackRouterEvent(
+                                OPENSTACK_ROUTER_INTERFACE_UPDATED,
+                                router(event.newValue().value().getId()),
+                                event.newValue().value()));
+                    });
+                    break;
+                case INSERT:
+                    log.debug("OpenStack router interface created {}", event.newValue());
+                    eventExecutor.execute(() -> {
+                        notifyDelegate(new OpenstackRouterEvent(
+                                OPENSTACK_ROUTER_INTERFACE_ADDED,
+                                router(event.newValue().value().getId()),
+                                event.newValue().value()));
+                    });
+                    break;
+                case REMOVE:
+                    log.debug("OpenStack router interface removed {}", event.oldValue());
+                    eventExecutor.execute(() -> {
+                        notifyDelegate(new OpenstackRouterEvent(
+                                OPENSTACK_ROUTER_INTERFACE_REMOVED,
+                                router(event.oldValue().value().getId()),
+                                event.oldValue().value()));
+                    });
+                    break;
+                default:
+                    log.error("Unsupported event type");
+                    break;
+            }
+        }
+    }
+
+    private class OpenstackFloatingIpMapListener implements MapEventListener<String, NetFloatingIP> {
+
+        @Override
+        public void event(MapEvent<String, NetFloatingIP> event) {
+            switch (event.type()) {
+                case UPDATE:
+                    log.debug("OpenStack floating IP updated {}", event.newValue());
+                    eventExecutor.execute(() -> {
+                        Router osRouter = Strings.isNullOrEmpty(
+                                event.newValue().value().getRouterId()) ?
+                                null :
+                                router(event.newValue().value().getRouterId());
+                        notifyDelegate(new OpenstackRouterEvent(
+                                OPENSTACK_FLOATING_IP_UPDATED,
+                                osRouter,
+                                event.newValue().value()));
+                        processFloatingIpUpdate(event, osRouter);
+                    });
+                    break;
+                case INSERT:
+                    log.debug("OpenStack floating IP created {}", event.newValue());
+                    eventExecutor.execute(() -> {
+                        Router osRouter = Strings.isNullOrEmpty(
+                                event.newValue().value().getRouterId()) ?
+                                null :
+                                router(event.newValue().value().getRouterId());
+                        notifyDelegate(new OpenstackRouterEvent(
+                                OPENSTACK_FLOATING_IP_CREATED,
+                                osRouter,
+                                event.newValue().value()));
+                    });
+                    break;
+                case REMOVE:
+                    log.debug("OpenStack floating IP removed {}", event.oldValue());
+                    eventExecutor.execute(() -> {
+                        Router osRouter = Strings.isNullOrEmpty(
+                                event.oldValue().value().getRouterId()) ?
+                                null :
+                                router(event.oldValue().value().getRouterId());
+                        notifyDelegate(new OpenstackRouterEvent(
+                                OPENSTACK_FLOATING_IP_REMOVED,
+                                osRouter,
+                                event.oldValue().value()));
+                    });
+                    break;
+                default:
+                    log.error("Unsupported event type");
+                    break;
+            }
+        }
+
+        private void processFloatingIpUpdate(MapEvent<String, NetFloatingIP> event,
+                                             Router osRouter) {
+            String oldPortId = event.oldValue().value().getPortId();
+            String newPortId = event.newValue().value().getPortId();
+
+            if (Strings.isNullOrEmpty(oldPortId) && !Strings.isNullOrEmpty(newPortId)) {
+                notifyDelegate(new OpenstackRouterEvent(
+                        OPENSTACK_FLOATING_IP_ASSOCIATED,
+                        osRouter,
+                        event.newValue().value(), newPortId));
+            }
+            if (!Strings.isNullOrEmpty(oldPortId) && Strings.isNullOrEmpty(newPortId)) {
+                notifyDelegate(new OpenstackRouterEvent(
+                        OPENSTACK_FLOATING_IP_DISASSOCIATED,
+                        osRouter,
+                        event.newValue().value(), oldPortId));
+            }
+        }
+    }
+}
