diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFloatingIpManager.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFloatingIpManager.java
new file mode 100644
index 0000000..602b0f7
--- /dev/null
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFloatingIpManager.java
@@ -0,0 +1,404 @@
+/*
+ * 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.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.util.KryoNamespace;
+import org.onlab.util.Tools;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.PortNumber;
+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.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.host.HostService;
+import org.onosproject.openstackinterface.OpenstackFloatingIP;
+import org.onosproject.openstackinterface.OpenstackInterfaceService;
+import org.onosproject.openstacknetworking.api.Constants;
+import org.onosproject.openstacknetworking.api.OpenstackFloatingIpService;
+import org.onosproject.openstacknode.OpenstackNode;
+import org.onosproject.openstacknode.OpenstackNodeEvent;
+import org.onosproject.openstacknode.OpenstackNodeListener;
+import org.onosproject.openstacknode.OpenstackNodeService;
+import org.onosproject.scalablegateway.api.ScalableGatewayService;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.Versioned;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.ExecutorService;
+
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.openstacknetworking.api.Constants.*;
+import static org.onosproject.openstacknetworking.impl.RulePopulatorUtil.buildExtension;
+
+
+@Service
+@Component(immediate = true)
+public class OpenstackFloatingIpManager extends AbstractVmHandler implements OpenstackFloatingIpService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenstackNodeService nodeService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ScalableGatewayService gatewayService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenstackInterfaceService openstackService;
+
+    private static final String NOT_ASSOCIATED = "null";
+    private static final KryoNamespace.Builder FLOATING_IP_SERIALIZER =
+            KryoNamespace.newBuilder().register(KryoNamespaces.API);
+
+    private final ExecutorService eventExecutor = newSingleThreadScheduledExecutor(
+            groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
+    private final InternalNodeListener nodeListener = new InternalNodeListener();
+    private ConsistentMap<IpAddress, Host> floatingIpMap;
+
+    private ApplicationId appId;
+
+    @Activate
+    protected void activate() {
+        super.activate();
+        appId = coreService.registerApplication(ROUTING_APP_ID);
+        nodeService.addListener(nodeListener);
+        floatingIpMap = storageService.<IpAddress, Host>consistentMapBuilder()
+                .withSerializer(Serializer.using(FLOATING_IP_SERIALIZER.build()))
+                .withName("openstackrouting-floatingip")
+                .withApplicationId(appId)
+                .build();
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        super.deactivate();
+        nodeService.removeListener(nodeListener);
+        log.info("Stopped");
+    }
+
+    @Override
+    protected void hostDetected(Host host) {
+        IpAddress hostIp = host.ipAddresses().stream().findFirst().get();
+        Optional<OpenstackFloatingIP> floatingIp = openstackService.floatingIps().stream()
+                .filter(fip -> fip.fixedIpAddress() != null && fip.fixedIpAddress().equals(hostIp))
+                .findFirst();
+        if (floatingIp.isPresent()) {
+            eventExecutor.execute(() -> associateFloatingIp(floatingIp.get()));
+        }
+    }
+
+    @Override
+    protected void hostRemoved(Host host) {
+        IpAddress hostIp = host.ipAddresses().stream().findFirst().get();
+        Optional<OpenstackFloatingIP> floatingIp = openstackService.floatingIps().stream()
+                .filter(fip -> fip.fixedIpAddress() != null && fip.fixedIpAddress().equals(hostIp))
+                .findFirst();
+        if (floatingIp.isPresent()) {
+            eventExecutor.execute(() -> disassociateFloatingIp(floatingIp.get()));
+        }
+    }
+
+    @Override
+    public void reinstallVmFlow(Host host) {
+        if (host == null) {
+            hostService.getHosts().forEach(h -> {
+                hostDetected(h);
+                log.info("Re-Install data plane flow of virtual machine {}", h);
+            });
+        } else {
+            hostDetected(host);
+            log.info("Re-Install data plane flow of virtual machine {}", host);
+        }
+    }
+
+    @Override
+    public void purgeVmFlow(Host host) {
+        if (host == null) {
+            hostService.getHosts().forEach(h -> {
+                hostRemoved(h);
+                log.info("Purge data plane flow of virtual machine {}", h);
+            });
+        } else {
+            hostRemoved(host);
+            log.info("Purge data plane flow of virtual machine {}", host);
+        }
+    }
+
+    @Override
+    public void createFloatingIp(OpenstackFloatingIP floatingIp) {
+    }
+
+    @Override
+    public void updateFloatingIp(OpenstackFloatingIP floatingIp) {
+        if (Strings.isNullOrEmpty(floatingIp.portId()) ||
+                floatingIp.portId().equals(NOT_ASSOCIATED)) {
+            eventExecutor.execute(() -> disassociateFloatingIp(floatingIp));
+        } else {
+            eventExecutor.execute(() -> associateFloatingIp(floatingIp));
+        }
+    }
+
+    @Override
+    public void deleteFloatingIp(String floatingIpId) {
+    }
+
+    private void associateFloatingIp(OpenstackFloatingIP floatingIp) {
+        Optional<Host> associatedVm = Tools.stream(hostService.getHosts())
+                .filter(host -> Objects.equals(
+                        host.annotations().value(PORT_ID),
+                        floatingIp.portId()))
+                .findAny();
+        if (!associatedVm.isPresent()) {
+            log.warn("Failed to associate floating IP({}) to port:{}",
+                     floatingIp.floatingIpAddress(),
+                     floatingIp.portId());
+            return;
+        }
+
+        floatingIpMap.put(floatingIp.floatingIpAddress(), associatedVm.get());
+        populateFloatingIpRules(floatingIp.floatingIpAddress(), associatedVm.get());
+
+        log.info("Associated floating IP {} to fixed IP {}",
+                 floatingIp.floatingIpAddress(), floatingIp.fixedIpAddress());
+    }
+
+    private void disassociateFloatingIp(OpenstackFloatingIP floatingIp) {
+        Versioned<Host> associatedVm = floatingIpMap.remove(floatingIp.floatingIpAddress());
+        if (associatedVm == null) {
+            log.warn("Failed to disassociate floating IP({})",
+                     floatingIp.floatingIpAddress());
+            // No VM is actually associated with the floating IP, do nothing
+            return;
+        }
+
+        removeFloatingIpRules(floatingIp.floatingIpAddress(), associatedVm.value());
+        log.info("Disassociated floating IP {} from fixed IP {}",
+                 floatingIp.floatingIpAddress(),
+                 associatedVm.value().ipAddresses());
+    }
+
+    private void populateFloatingIpRules(IpAddress floatingIp, Host associatedVm) {
+        populateFloatingIpIncomingRules(floatingIp, associatedVm);
+        populateFloatingIpOutgoingRules(floatingIp, associatedVm);
+    }
+
+    private void removeFloatingIpRules(IpAddress floatingIp, Host associatedVm) {
+        Optional<IpAddress> fixedIp = associatedVm.ipAddresses().stream().findFirst();
+        if (!fixedIp.isPresent()) {
+            log.warn("Failed to remove floating IP({}) from {}",
+                     floatingIp, associatedVm);
+            return;
+        }
+
+        TrafficSelector.Builder sOutgoingBuilder = DefaultTrafficSelector.builder();
+        TrafficSelector.Builder sIncomingBuilder = DefaultTrafficSelector.builder();
+
+        sOutgoingBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                .matchTunnelId(Long.valueOf(associatedVm.annotations().value(VXLAN_ID)))
+                .matchIPSrc(fixedIp.get().toIpPrefix());
+
+        sIncomingBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(floatingIp.toIpPrefix());
+
+        gatewayService.getGatewayDeviceIds().forEach(deviceId -> {
+            TrafficSelector.Builder sForTrafficFromVmBuilder = DefaultTrafficSelector.builder()
+                    .matchEthType(Ethernet.TYPE_IPV4)
+                    .matchIPDst(floatingIp.toIpPrefix())
+                    .matchInPort(nodeService.tunnelPort(deviceId).get());
+
+            RulePopulatorUtil.setRule(
+                    flowObjectiveService,
+                    appId,
+                    deviceId,
+                    sOutgoingBuilder.build(),
+                    DefaultTrafficTreatment.builder().build(),
+                    ForwardingObjective.Flag.VERSATILE,
+                    FLOATING_RULE_PRIORITY, false);
+
+            RulePopulatorUtil.setRule(
+                    flowObjectiveService,
+                    appId,
+                    deviceId,
+                    sIncomingBuilder.build(),
+                    DefaultTrafficTreatment.builder().build(),
+                    ForwardingObjective.Flag.VERSATILE,
+                    FLOATING_RULE_PRIORITY, false);
+
+            RulePopulatorUtil.setRule(
+                    flowObjectiveService,
+                    appId,
+                    deviceId,
+                    sForTrafficFromVmBuilder.build(),
+                    DefaultTrafficTreatment.builder().build(),
+                    ForwardingObjective.Flag.VERSATILE,
+                    FLOATING_RULE_FOR_TRAFFIC_FROM_VM_PRIORITY, false);
+        });
+    }
+
+    private void populateFloatingIpIncomingRules(IpAddress floatingIp, Host associatedVm) {
+        DeviceId cnodeId = associatedVm.location().deviceId();
+        Optional<IpAddress> dataIp = nodeService.dataIp(cnodeId);
+        Optional<IpAddress> fixedIp = associatedVm.ipAddresses().stream().findFirst();
+
+        if (!fixedIp.isPresent() || !dataIp.isPresent()) {
+            log.warn("Failed to associate floating IP({})", floatingIp);
+            return;
+        }
+
+        TrafficSelector selectorForTrafficFromExternal = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(floatingIp.toIpPrefix())
+                .build();
+
+        gatewayService.getGatewayDeviceIds().forEach(gnodeId -> {
+            TrafficTreatment treatmentForTrafficFromExternal = DefaultTrafficTreatment.builder()
+                    .setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
+                    .setEthDst(associatedVm.mac())
+                    .setIpDst(associatedVm.ipAddresses().stream().findFirst().get())
+                    .setTunnelId(Long.valueOf(associatedVm.annotations().value(VXLAN_ID)))
+                    .extension(buildExtension(deviceService, gnodeId, dataIp.get().getIp4Address()),
+                               gnodeId)
+                    .setOutput(nodeService.tunnelPort(gnodeId).get())
+                    .build();
+
+            ForwardingObjective forwardingObjectiveForTrafficFromExternal = DefaultForwardingObjective.builder()
+                    .withSelector(selectorForTrafficFromExternal)
+                    .withTreatment(treatmentForTrafficFromExternal)
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(FLOATING_RULE_PRIORITY)
+                    .fromApp(appId)
+                    .add();
+
+            flowObjectiveService.forward(gnodeId, forwardingObjectiveForTrafficFromExternal);
+
+
+            TrafficSelector selectorForTrafficFromVm = DefaultTrafficSelector.builder()
+                    .matchEthType(Ethernet.TYPE_IPV4)
+                    .matchIPDst(floatingIp.toIpPrefix())
+                    .matchInPort(nodeService.tunnelPort(gnodeId).get())
+                    .build();
+
+            TrafficTreatment treatmentForTrafficFromVm = DefaultTrafficTreatment.builder()
+                    .setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
+                    .setEthDst(associatedVm.mac())
+                    .setIpDst(associatedVm.ipAddresses().stream().findFirst().get())
+                    .setTunnelId(Long.valueOf(associatedVm.annotations().value(VXLAN_ID)))
+                    .extension(buildExtension(deviceService, gnodeId, dataIp.get().getIp4Address()),
+                            gnodeId)
+                    .setOutput(PortNumber.IN_PORT)
+                    .build();
+
+            ForwardingObjective forwardingObjectiveForTrafficFromVm = DefaultForwardingObjective.builder()
+                    .withSelector(selectorForTrafficFromVm)
+                    .withTreatment(treatmentForTrafficFromVm)
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(FLOATING_RULE_FOR_TRAFFIC_FROM_VM_PRIORITY)
+                    .fromApp(appId)
+                    .add();
+
+            flowObjectiveService.forward(gnodeId, forwardingObjectiveForTrafficFromVm);
+
+        });
+    }
+
+    private void populateFloatingIpOutgoingRules(IpAddress floatingIp, Host associatedVm) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchTunnelId(Long.valueOf(associatedVm.annotations().value(VXLAN_ID)))
+                .matchIPSrc(associatedVm.ipAddresses().stream().findFirst().get().toIpPrefix())
+                .build();
+
+        gatewayService.getGatewayDeviceIds().forEach(gnodeId -> {
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setIpSrc(floatingIp)
+                    .setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
+                    .setEthDst(Constants.DEFAULT_EXTERNAL_ROUTER_MAC)
+                    .setOutput(gatewayService.getUplinkPort(gnodeId))
+                    .build();
+
+            ForwardingObjective fo = DefaultForwardingObjective.builder()
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(FLOATING_RULE_PRIORITY)
+                    .fromApp(appId)
+                    .add();
+
+            flowObjectiveService.forward(gnodeId, fo);
+        });
+    }
+
+    // TODO consider the case that port with associated floating IP is attached to a VM
+
+    private class InternalNodeListener implements OpenstackNodeListener {
+
+        @Override
+        public void event(OpenstackNodeEvent event) {
+            OpenstackNode node = event.node();
+
+            switch (event.type()) {
+                case COMPLETE:
+                    reinstallVmFlow(null);
+                    break;
+                case INIT:
+                case DEVICE_CREATED:
+                case INCOMPLETE:
+                default:
+                    break;
+            }
+        }
+    }
+}
