diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackSyncStateCommand.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackSyncStateCommand.java
new file mode 100644
index 0000000..d07591e
--- /dev/null
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackSyncStateCommand.java
@@ -0,0 +1,251 @@
+/*
+ * 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.cli;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.base.Strings;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
+import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
+import org.onosproject.openstacknetworking.api.OpenstackRouterService;
+import org.openstack4j.api.OSClient;
+import org.openstack4j.api.exceptions.AuthenticationException;
+import org.openstack4j.model.identity.Access;
+import org.openstack4j.model.network.IP;
+import org.openstack4j.model.network.NetFloatingIP;
+import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.Port;
+import org.openstack4j.model.network.Router;
+import org.openstack4j.model.network.RouterInterface;
+import org.openstack4j.model.network.Subnet;
+import org.openstack4j.openstack.OSFactory;
+import org.openstack4j.openstack.networking.domain.NeutronRouterInterface;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import static org.openstack4j.core.transport.ObjectMapperSingleton.getContext;
+
+/**
+ * Synchronizes OpenStack network states.
+ */
+@Command(scope = "onos", name = "openstack-sync-states",
+        description = "Synchronizes all OpenStack network states")
+public class OpenstackSyncStateCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "endpoint", description = "OpenStack service endpoint",
+            required = true, multiValued = false)
+    private String endpoint = null;
+
+    @Argument(index = 1, name = "tenant", description = "OpenStack admin tenant name",
+            required = true, multiValued = false)
+    private String tenant = null;
+
+    @Argument(index = 2, name = "user", description = "OpenStack admin user name",
+            required = true, multiValued = false)
+    private String user = null;
+
+    @Argument(index = 3, name = "password", description = "OpenStack admin user password",
+            required = true, multiValued = false)
+    private String password = null;
+
+    private static final String NETWORK_FORMAT = "%-40s%-20s%-20s%-8s";
+    private static final String SUBNET_FORMAT = "%-40s%-20s%-20s";
+    private static final String PORT_FORMAT = "%-40s%-20s%-20s%-8s";
+    private static final String ROUTER_FORMAT = "%-40s%-20s%-20s%-8s";
+    private static final String FLOATING_IP_FORMAT = "%-40s%-20s%-20s";
+
+    private static final String DEVICE_OWNER_GW = "network:router_gateway";
+    private static final String DEVICE_OWNER_IFACE = "network:router_interface";
+
+    @Override
+    protected void execute() {
+        OpenstackNetworkAdminService osNetAdminService = get(OpenstackNetworkAdminService.class);
+        OpenstackNetworkService osNetService = get(OpenstackNetworkService.class);
+        OpenstackRouterAdminService osRouterAdminService = get(OpenstackRouterAdminService.class);
+        OpenstackRouterService osRouterService = get(OpenstackRouterService.class);
+
+        Access osAccess;
+        try {
+            osAccess = OSFactory.builder()
+                    .endpoint(this.endpoint)
+                    .tenantName(this.tenant)
+                    .credentials(this.user, this.password)
+                    .authenticate()
+                    .getAccess();
+        } catch (AuthenticationException e) {
+            print("Authentication failed");
+            return;
+        } catch (Exception e) {
+            print("Failed to access OpenStack service");
+            return;
+        }
+
+        OSClient osClient = OSFactory.clientFromAccess(osAccess);
+
+        print("Synchronizing OpenStack networks...");
+        print(NETWORK_FORMAT, "ID", "Name", "VNI", "Subnets");
+        osClient.networking().network().list().forEach(osNet -> {
+            if (osNetService.network(osNet.getId()) != null) {
+                osNetAdminService.updateNetwork(osNet);
+            } else {
+                osNetAdminService.createNetwork(osNet);
+            }
+            printNetwork(osNet);
+        });
+
+        print("\nSynchronizing OpenStack subnets...");
+        print(SUBNET_FORMAT, "ID", "Network", "CIDR");
+        osClient.networking().subnet().list().forEach(osSubnet -> {
+            if (osNetService.subnet(osSubnet.getId()) != null) {
+                osNetAdminService.updateSubnet(osSubnet);
+            } else {
+                osNetAdminService.createSubnet(osSubnet);
+            }
+            printSubnet(osSubnet, osNetService);
+        });
+
+        print("\nSynchronizing OpenStack ports...");
+        print(PORT_FORMAT, "ID", "Network", "MAC", "Fixed IPs");
+        osClient.networking().port().list().forEach(osPort -> {
+            if (osNetService.port(osPort.getId()) != null) {
+                osNetAdminService.updatePort(osPort);
+            } else {
+                osNetAdminService.createPort(osPort);
+            }
+            printPort(osPort, osNetService);
+        });
+
+        print("\nSynchronizing OpenStack routers...");
+        print(ROUTER_FORMAT, "ID", "Name", "External", "Internal");
+        osClient.networking().router().list().forEach(osRouter -> {
+            if (osRouterService.router(osRouter.getId()) != null) {
+                osRouterAdminService.updateRouter(osRouter);
+            } else {
+                osRouterAdminService.createRouter(osRouter);
+            }
+
+            // FIXME do we need to manage router interfaces separately?
+            osNetService.ports().stream()
+                    .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
+                            Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_IFACE))
+                    .forEach(osPort -> addRouterIface(osPort, osRouterService,
+                            osRouterAdminService));
+
+            printRouter(osRouter, osNetService);
+        });
+
+        print("\nSynchronizing OpenStack floating IPs...");
+        print(FLOATING_IP_FORMAT, "ID", "Floating IP", "Fixed IP");
+        osClient.networking().floatingip().list().forEach(osFloating -> {
+            if (osRouterService.floatingIp(osFloating.getId()) != null) {
+                osRouterAdminService.updateFloatingIp(osFloating);
+            } else {
+                osRouterAdminService.createFloatingIp(osFloating);
+            }
+            printFloatingIp(osFloating);
+        });
+    }
+
+    // TODO fix the logic to add router interface to router
+    private void addRouterIface(Port osPort, OpenstackRouterService service,
+                                OpenstackRouterAdminService adminService) {
+        osPort.getFixedIps().forEach(p -> {
+            JsonNode jsonTree = mapper().createObjectNode()
+                    .put("id", osPort.getDeviceId())
+                    .put("tenant_id", osPort.getTenantId())
+                    .put("subnet_id", p.getSubnetId())
+                    .put("port_id", osPort.getId());
+            try {
+                RouterInterface rIface = getContext(NeutronRouterInterface.class)
+                        .readerFor(NeutronRouterInterface.class)
+                        .readValue(jsonTree);
+                if (service.routerInterface(rIface.getPortId()) != null) {
+                    adminService.updateRouterInterface(rIface);
+                } else {
+                    adminService.addRouterInterface(rIface);
+                }
+            } catch (IOException ignore) {
+            }
+        });
+    }
+
+    private void printNetwork(Network osNet) {
+        final String strNet = String.format(NETWORK_FORMAT,
+                osNet.getId(),
+                osNet.getName(),
+                osNet.getProviderSegID(),
+                osNet.getSubnets());
+        print(strNet);
+    }
+
+    private void printSubnet(Subnet osSubnet, OpenstackNetworkService osNetService) {
+        final String strSubnet = String.format(SUBNET_FORMAT,
+                osSubnet.getId(),
+                osNetService.network(osSubnet.getNetworkId()).getName(),
+                osSubnet.getCidr());
+        print(strSubnet);
+    }
+
+    private void printPort(Port osPort, OpenstackNetworkService osNetService) {
+        List<String> fixedIps = osPort.getFixedIps().stream()
+                .map(IP::getIpAddress)
+                .collect(Collectors.toList());
+        final String strPort = String.format(PORT_FORMAT,
+                osPort.getId(),
+                osNetService.network(osPort.getNetworkId()).getName(),
+                osPort.getMacAddress(),
+                fixedIps.isEmpty() ? "" : fixedIps);
+        print(strPort);
+    }
+
+    private void printRouter(Router osRouter, OpenstackNetworkService osNetService) {
+        List<String> externals = osNetService.ports().stream()
+                .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
+                        Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_GW))
+                .flatMap(osPort -> osPort.getFixedIps().stream())
+                .map(IP::getIpAddress)
+                .collect(Collectors.toList());
+
+        List<String> internals = osNetService.ports().stream()
+                .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
+                        Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_IFACE))
+                .flatMap(osPort -> osPort.getFixedIps().stream())
+                .map(IP::getIpAddress)
+                .collect(Collectors.toList());
+
+        final String strRouter = String.format(ROUTER_FORMAT,
+                osRouter.getId(),
+                osRouter.getName(),
+                externals.isEmpty() ? "" : externals,
+                internals.isEmpty() ? "" : internals);
+        print(strRouter);
+    }
+
+    private void printFloatingIp(NetFloatingIP floatingIp) {
+        final String strFloating = String.format(FLOATING_IP_FORMAT,
+                floatingIp.getId(),
+                floatingIp.getFixedIpAddress(),
+                Strings.isNullOrEmpty(floatingIp.getFixedIpAddress()) ?
+                        "" : floatingIp.getFixedIpAddress());
+        print(strFloating);
+    }
+}
