diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
new file mode 100644
index 0000000..50d9b37
--- /dev/null
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
@@ -0,0 +1,239 @@
+/*
+* Copyright 2016-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 org.apache.felix.scr.annotations.Activate;
+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.onlab.packet.Ethernet;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.openstacknetworking.api.InstancePort;
+import org.onosproject.openstacknetworking.api.InstancePortEvent;
+import org.onosproject.openstacknetworking.api.InstancePortListener;
+import org.onosproject.openstacknetworking.api.InstancePortService;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
+import org.onosproject.openstacknode.OpenstackNode;
+import org.onosproject.openstacknode.OpenstackNodeService;
+import org.openstack4j.model.network.Network;
+import org.slf4j.Logger;
+
+import java.util.concurrent.ExecutorService;
+
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.openstacknetworking.api.Constants.*;
+import static org.onosproject.openstacknetworking.impl.RulePopulatorUtil.buildExtension;
+import static org.slf4j.LoggerFactory.getLogger;
+
+
+/**
+ * Populates switching flow rules on OVS for the basic connectivity among the
+ * virtual instances in the same network.
+ */
+@Component(immediate = true)
+public final class OpenstackSwitchingHandler {
+
+    private final Logger log = getLogger(getClass());
+
+    private static final String ERR_SET_FLOWS = "Failed to set flows for %s: ";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InstancePortService instancePortService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenstackNetworkService osNetworkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenstackNodeService osNodeService;
+
+    private final ExecutorService eventExecutor = newSingleThreadExecutor(
+            groupedThreads(this.getClass().getSimpleName(), "event-handler"));
+    private final InstancePortListener instancePortListener = new InternalInstancePortListener();
+    private ApplicationId appId;
+
+    @Activate
+    protected void activate() {
+        appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
+        instancePortService.addListener(instancePortListener);
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        instancePortService.removeListener(instancePortListener);
+        eventExecutor.shutdown();
+
+        log.info("Stopped");
+    }
+
+    private void setNetworkRules(InstancePort instPort, boolean install) {
+        setTunnelTagFlowRules(instPort, install);
+        setForwardingRules(instPort, install);
+    }
+
+    private void setForwardingRules(InstancePort instPort, boolean install) {
+        // switching rules for the instPorts in the same node
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(instPort.ipAddress().toIpPrefix())
+                .matchTunnelId(getVni(instPort))
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setEthDst(instPort.macAddress())
+                .setOutput(instPort.portNumber())
+                .build();
+
+        RulePopulatorUtil.setRule(
+                flowObjectiveService,
+                appId,
+                instPort.deviceId(),
+                selector,
+                treatment,
+                ForwardingObjective.Flag.SPECIFIC,
+                PRIORITY_SWITCHING_RULE,
+                install);
+
+        // switching rules for the instPorts in the remote node
+        for (OpenstackNode osNode : osNodeService.completeNodes()) {
+            if (osNode.intBridge().equals(instPort.deviceId())) {
+                continue;
+            }
+
+            TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
+                    .extension(buildExtension(
+                            deviceService,
+                            osNode.intBridge(),
+                            osNodeService.dataIp(instPort.deviceId()).get().getIp4Address()),
+                            osNode.intBridge())
+                    .setOutput(osNodeService.tunnelPort(osNode.intBridge()).get())
+                    .build();
+
+            RulePopulatorUtil.setRule(
+                    flowObjectiveService,
+                    appId,
+                    osNode.intBridge(),
+                    selector,
+                    treatmentToRemote,
+                    ForwardingObjective.Flag.SPECIFIC,
+                    PRIORITY_SWITCHING_RULE,
+                    install);
+        }
+    }
+
+    private void setTunnelTagFlowRules(InstancePort instPort, boolean install) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchInPort(instPort.portNumber())
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setTunnelId(getVni(instPort))
+                .build();
+
+        RulePopulatorUtil.setRule(
+                flowObjectiveService,
+                appId,
+                instPort.deviceId(),
+                selector,
+                treatment,
+                ForwardingObjective.Flag.SPECIFIC,
+                PRIORITY_TUNNEL_TAG_RULE,
+                install);
+    }
+
+    private Long getVni(InstancePort instPort) {
+        Network osNet = osNetworkService.network(instPort.networkId());
+        if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
+            final String error = String.format(
+                    ERR_SET_FLOWS + "Failed to get VNI for %s",
+                    instPort, osNet.getName());
+            throw new IllegalStateException(error);
+        }
+        return Long.valueOf(osNet.getProviderSegID());
+    }
+
+    private class InternalInstancePortListener implements InstancePortListener {
+
+        @Override
+        public boolean isRelevant(InstancePortEvent event) {
+            InstancePort instPort = event.subject();
+            return mastershipService.isLocalMaster(instPort.deviceId());
+        }
+
+        @Override
+        public void event(InstancePortEvent event) {
+            InstancePort instPort = event.subject();
+            switch (event.type()) {
+                case OPENSTACK_INSTANCE_PORT_UPDATED:
+                case OPENSTACK_INSTANCE_PORT_DETECTED:
+                    eventExecutor.execute(() -> {
+                        log.info("Instance port detected MAC:{} IP:{}",
+                                instPort.macAddress(),
+                                instPort.ipAddress());
+                        instPortDetected(event.subject());
+                    });
+                    break;
+                case OPENSTACK_INSTANCE_PORT_VANISHED:
+                    eventExecutor.execute(() -> {
+                        log.info("Instance port vanished MAC:{} IP:{}",
+                                instPort.macAddress(),
+                                instPort.ipAddress());
+                        instPortRemoved(event.subject());
+                    });
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        private void instPortDetected(InstancePort instPort) {
+            setNetworkRules(instPort, true);
+            // TODO add something else if needed
+        }
+
+        private void instPortRemoved(InstancePort instPort) {
+            setNetworkRules(instPort, false);
+            // TODO add something else if needed
+        }
+    }
+}
