diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java
new file mode 100644
index 0000000..9f944da
--- /dev/null
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright 2015 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.vtnrsc.floatingip.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+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.IpAddress;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.EventuallyConsistentMapEvent;
+import org.onosproject.store.service.EventuallyConsistentMapListener;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.vtnrsc.DefaultFloatingIp;
+import org.onosproject.vtnrsc.FloatingIp;
+import org.onosproject.vtnrsc.FloatingIpId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.RouterId;
+import org.onosproject.vtnrsc.floatingip.FloatingIpEvent;
+import org.onosproject.vtnrsc.floatingip.FloatingIpListener;
+import org.onosproject.vtnrsc.floatingip.FloatingIpService;
+import org.onosproject.vtnrsc.router.RouterService;
+import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+import org.slf4j.Logger;
+
+import com.google.common.collect.Sets;
+
+/**
+ * Provides implementation of the FloatingIp service.
+ */
+@Component(immediate = true)
+@Service
+public class FloatingIpManager implements FloatingIpService {
+    private static final String FLOATINGIP_ID_NOT_NULL = "Floatingip ID cannot be null";
+    private static final String FLOATINGIP_NOT_NULL = "Floatingip cannot be null";
+    private static final String FLOATINGIP = "vtn-floatingip-store";
+    private static final String VTNRSC_APP = "org.onosproject.vtnrsc";
+    private static final String LISTENER_NOT_NULL = "Listener cannot be null";
+    private static final String EVENT_NOT_NULL = "event cannot be null";
+
+    private final Logger log = getLogger(getClass());
+    private final Set<FloatingIpListener> listeners = Sets
+            .newCopyOnWriteArraySet();
+    private EventuallyConsistentMapListener<FloatingIpId, FloatingIp> floatingIpListener =
+            new InnerFloatingIpStoreListener();
+    protected EventuallyConsistentMap<FloatingIpId, FloatingIp> floatingIpStore;
+    protected ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TenantNetworkService tenantNetworkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VirtualPortService virtualPortService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RouterService routerService;
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(VTNRSC_APP);
+        KryoNamespace.Builder serializer = KryoNamespace
+                .newBuilder()
+                .register(KryoNamespaces.API)
+                .register(FloatingIp.class, FloatingIpId.class,
+                          TenantNetworkId.class, TenantId.class,
+                          FloatingIp.Status.class, RouterId.class,
+                          VirtualPortId.class, DefaultFloatingIp.class);
+        floatingIpStore = storageService
+                .<FloatingIpId, FloatingIp>eventuallyConsistentMapBuilder()
+                .withName(FLOATINGIP).withSerializer(serializer)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+        floatingIpStore.addListener(floatingIpListener);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        floatingIpStore.removeListener(floatingIpListener);
+        floatingIpStore.destroy();
+        listeners.clear();
+        log.info("Stopped");
+    }
+
+    @Override
+    public Collection<FloatingIp> getFloatingIps() {
+        return Collections.unmodifiableCollection(floatingIpStore.values());
+    }
+
+    @Override
+    public FloatingIp getFloatingIp(FloatingIpId floatingIpId) {
+        checkNotNull(floatingIpId, FLOATINGIP_ID_NOT_NULL);
+        return floatingIpStore.get(floatingIpId);
+    }
+
+    @Override
+    public boolean exists(FloatingIpId floatingIpId) {
+        checkNotNull(floatingIpId, FLOATINGIP_ID_NOT_NULL);
+        return floatingIpStore.containsKey(floatingIpId);
+    }
+
+    @Override
+    public boolean floatingIpIsUsed(IpAddress floatingIpAddr,
+                                    FloatingIpId floatingIpId) {
+        checkNotNull(floatingIpAddr, "Floating IP address cannot be null");
+        checkNotNull(floatingIpId, "Floating IP Id cannot be null");
+        Collection<FloatingIp> floatingIps = getFloatingIps();
+        for (FloatingIp floatingIp : floatingIps) {
+            if (floatingIp.floatingIp().equals(floatingIpAddr)
+                    && !floatingIp.id().equals(floatingIpId)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean fixedIpIsUsed(IpAddress fixedIpAddr, TenantId tenantId,
+                                 FloatingIpId floatingIpId) {
+        checkNotNull(fixedIpAddr, "Fixed IP address cannot be null");
+        checkNotNull(tenantId, "Tenant Id cannot be null");
+        checkNotNull(floatingIpId, "Floating IP Id cannot be null");
+        Collection<FloatingIp> floatingIps = getFloatingIps();
+        for (FloatingIp floatingIp : floatingIps) {
+            IpAddress fixedIp = floatingIp.fixedIp();
+            if (fixedIp != null) {
+                if (fixedIp.equals(fixedIpAddr)
+                        && floatingIp.tenantId().equals(tenantId)
+                        && !floatingIp.id().equals(floatingIpId)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean createFloatingIps(Collection<FloatingIp> floatingIps) {
+        checkNotNull(floatingIps, FLOATINGIP_NOT_NULL);
+        boolean result = true;
+        for (FloatingIp floatingIp : floatingIps) {
+            verifyFloatingIpData(floatingIp);
+            if (floatingIp.portId() != null) {
+                floatingIpStore.put(floatingIp.id(), floatingIp);
+                if (!floatingIpStore.containsKey(floatingIp.id())) {
+                    log.debug("The floating Ip is created failed whose identifier is {}",
+                              floatingIp.id().toString());
+                    result = false;
+                }
+            } else {
+                FloatingIp oldFloatingIp = floatingIpStore.get(floatingIp.id());
+                if (oldFloatingIp != null) {
+                    floatingIpStore.remove(floatingIp.id(), oldFloatingIp);
+                    if (floatingIpStore.containsKey(floatingIp.id())) {
+                        log.debug("The floating Ip is created failed whose identifier is {}",
+                                  floatingIp.id().toString());
+                        result = false;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean updateFloatingIps(Collection<FloatingIp> floatingIps) {
+        checkNotNull(floatingIps, FLOATINGIP_NOT_NULL);
+        boolean result = true;
+        if (floatingIps != null) {
+            for (FloatingIp floatingIp : floatingIps) {
+                verifyFloatingIpData(floatingIp);
+                if (floatingIp.portId() != null) {
+                    floatingIpStore.put(floatingIp.id(), floatingIp);
+                    if (!floatingIpStore.containsKey(floatingIp.id())) {
+                        log.debug("The floating Ip is updated failed whose identifier is {}",
+                                  floatingIp.id().toString());
+                        result = false;
+                    }
+                } else {
+                    FloatingIp oldFloatingIp = floatingIpStore.get(floatingIp
+                            .id());
+                    if (oldFloatingIp != null) {
+                        floatingIpStore.remove(floatingIp.id(), oldFloatingIp);
+                        if (floatingIpStore.containsKey(floatingIp.id())) {
+                            log.debug("The floating Ip is updated failed whose identifier is {}",
+                                      floatingIp.id().toString());
+                            result = false;
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean removeFloatingIps(Collection<FloatingIpId> floatingIpIds) {
+        checkNotNull(floatingIpIds, FLOATINGIP_ID_NOT_NULL);
+        boolean result = true;
+        if (floatingIpIds != null) {
+            for (FloatingIpId floatingIpId : floatingIpIds) {
+                if (!floatingIpStore.containsKey(floatingIpId)) {
+                    log.debug("The floatingIp is not exist whose identifier is {}",
+                              floatingIpId.toString());
+                    throw new IllegalArgumentException(
+                                                       "FloatingIP ID doesn't exist");
+                }
+                FloatingIp floatingIp = floatingIpStore.get(floatingIpId);
+                floatingIpStore.remove(floatingIpId, floatingIp);
+                if (floatingIpStore.containsKey(floatingIpId)) {
+                    log.debug("The floating Ip is deleted failed whose identifier is {}",
+                              floatingIpId.toString());
+                    result = false;
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public void addListener(FloatingIpListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeListener(FloatingIpListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.add(listener);
+    }
+
+    /**
+     * Verifies validity of FloatingIp data.
+     *
+     * @param floatingIps floatingIp instance
+     */
+    private void verifyFloatingIpData(FloatingIp floatingIps) {
+        checkNotNull(floatingIps, FLOATINGIP_NOT_NULL);
+        if (!tenantNetworkService.exists(floatingIps.networkId())) {
+            log.debug("The network identifier {} that the floating Ip {} create for is not exist",
+                      floatingIps.networkId().toString(), floatingIps.id()
+                              .toString());
+            throw new IllegalArgumentException(
+                                               "Floating network ID doesn't exist");
+        }
+
+        VirtualPortId portId = floatingIps.portId();
+        if (portId != null && !virtualPortService.exists(portId)) {
+            log.debug("The port identifier {} that the floating Ip {} create for is not exist",
+                      floatingIps.portId().toString(), floatingIps.id()
+                              .toString());
+            throw new IllegalArgumentException("Port ID doesn't exist");
+        }
+
+        RouterId routerId = floatingIps.routerId();
+        if (routerId != null && !routerService.exists(routerId)) {
+            log.debug("The router identifier {} that the floating Ip {} create for is not exist",
+                      floatingIps.routerId().toString(), floatingIps.id()
+                              .toString());
+            throw new IllegalArgumentException("Router ID doesn't exist");
+        }
+
+        if (floatingIpIsUsed(floatingIps.floatingIp(), floatingIps.id())) {
+            log.debug("The floaing Ip {} that the floating Ip {} create for is used",
+                      floatingIps.floatingIp().toString(), floatingIps.id()
+                              .toString());
+            throw new IllegalArgumentException(
+                                               "The floating IP address is used");
+        }
+
+        IpAddress fixedIp = floatingIps.fixedIp();
+        if (fixedIp != null
+                && fixedIpIsUsed(fixedIp, floatingIps.tenantId(),
+                                 floatingIps.id())) {
+            log.debug("The fixed Ip {} that the floating Ip {} create for is used",
+                      floatingIps.fixedIp().toString(), floatingIps.id()
+                              .toString());
+            throw new IllegalArgumentException("The fixed IP address is used");
+        }
+    }
+
+    private class InnerFloatingIpStoreListener
+            implements
+            EventuallyConsistentMapListener<FloatingIpId, FloatingIp> {
+
+        @Override
+        public void event(EventuallyConsistentMapEvent<FloatingIpId, FloatingIp> event) {
+            checkNotNull(event, EVENT_NOT_NULL);
+            FloatingIp floatingIp = event.value();
+            if (EventuallyConsistentMapEvent.Type.PUT == event.type()) {
+                notifyListeners(new FloatingIpEvent(
+                                                    FloatingIpEvent.Type.FLOATINGIP_PUT,
+                                                    floatingIp));
+            }
+            if (EventuallyConsistentMapEvent.Type.REMOVE == event.type()) {
+                notifyListeners(new FloatingIpEvent(
+                                                    FloatingIpEvent.Type.FLOATINGIP_DELETE,
+                                                    floatingIp));
+            }
+        }
+    }
+
+    /**
+     * Notifies specify event to all listeners.
+     *
+     * @param event Floating IP event
+     */
+    private void notifyListeners(FloatingIpEvent event) {
+        checkNotNull(event, EVENT_NOT_NULL);
+        listeners.forEach(listener -> listener.event(event));
+    }
+}
