diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/VpnPortManager.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/VpnPortManager.java
new file mode 100755
index 0000000..18ff172
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/VpnPortManager.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.evpnopenflow.rsc.vpnport.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Sets;
+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.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.evpnopenflow.rsc.BasePort;
+import org.onosproject.evpnopenflow.rsc.BasePortId;
+import org.onosproject.evpnopenflow.rsc.DefaultVpnPort;
+import org.onosproject.evpnopenflow.rsc.VpnInstanceId;
+import org.onosproject.evpnopenflow.rsc.VpnPort;
+import org.onosproject.evpnopenflow.rsc.VpnPortId;
+import org.onosproject.evpnopenflow.rsc.baseport.BasePortService;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortEvent;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortListener;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.vtnrsc.AllocationPool;
+import org.onosproject.vtnrsc.BindingHostId;
+import org.onosproject.vtnrsc.DefaultSubnet;
+import org.onosproject.vtnrsc.DefaultTenantNetwork;
+import org.onosproject.vtnrsc.DefaultVirtualPort;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.HostRoute;
+import org.onosproject.vtnrsc.PhysicalNetwork;
+import org.onosproject.vtnrsc.SegmentationId;
+import org.onosproject.vtnrsc.Subnet;
+import org.onosproject.vtnrsc.SubnetId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetwork;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.subnet.SubnetService;
+import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVENT_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_PORT_START;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_PORT_STOP;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INTERFACE_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.JSON_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_CREATION_FAILED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_DELETE_FAILED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_ID_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_IS_NOT_EXIST;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_STORE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_UPDATE_FAILED;
+
+/**
+ * Provides implementation of the VpnPort service.
+ */
+@Component(immediate = true)
+@Service
+public class VpnPortManager implements VpnPortService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private final Set<VpnPortListener> listeners = Sets
+            .newCopyOnWriteArraySet();
+
+    protected EventuallyConsistentMap<VpnPortId, VpnPort> vpnPortStore;
+    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 BasePortService basePortService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VirtualPortService virtualPortService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TenantNetworkService tenantNetworkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected SubnetService subnetService;
+
+    @Activate
+
+    public void activate() {
+        appId = coreService.registerApplication(APP_ID);
+        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API).register(VpnPort.class)
+                .register(VpnPortId.class);
+        vpnPortStore = storageService
+                .<VpnPortId, VpnPort>eventuallyConsistentMapBuilder()
+                .withName(VPN_PORT_STORE).withSerializer(serializer)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+        log.info(EVPN_VPN_PORT_START);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        vpnPortStore.destroy();
+        log.info(EVPN_VPN_PORT_STOP);
+    }
+
+    @Override
+    public boolean exists(VpnPortId vpnPortId) {
+        checkNotNull(vpnPortId, VPN_PORT_ID_NOT_NULL);
+        return vpnPortStore.containsKey(vpnPortId);
+    }
+
+    @Override
+    public VpnPort getPort(VpnPortId vpnPortId) {
+        checkNotNull(vpnPortId, VPN_PORT_ID_NOT_NULL);
+        return vpnPortStore.get(vpnPortId);
+    }
+
+    @Override
+    public Collection<VpnPort> getPorts() {
+        return Collections.unmodifiableCollection(vpnPortStore.values());
+    }
+
+    @Override
+    public boolean createPorts(Iterable<VpnPort> vpnPorts) {
+        checkNotNull(vpnPorts, VPN_PORT_NOT_NULL);
+        for (VpnPort vpnPort : vpnPorts) {
+            log.info(VPN_PORT_ID, vpnPort.id().toString());
+            vpnPortStore.put(vpnPort.id(), vpnPort);
+            if (!vpnPortStore.containsKey(vpnPort.id())) {
+                log.info(VPN_PORT_CREATION_FAILED, vpnPort.id().toString());
+                return false;
+            }
+            notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_SET,
+                                             vpnPort));
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updatePorts(Iterable<VpnPort> vpnPorts) {
+        checkNotNull(vpnPorts, VPN_PORT_NOT_NULL);
+        for (VpnPort vpnPort : vpnPorts) {
+            if (!vpnPortStore.containsKey(vpnPort.id())) {
+                log.info(VPN_PORT_IS_NOT_EXIST, vpnPort.id().toString());
+                return false;
+            }
+            vpnPortStore.put(vpnPort.id(), vpnPort);
+            if (!vpnPort.equals(vpnPortStore.get(vpnPort.id()))) {
+                log.info(VPN_PORT_UPDATE_FAILED, vpnPort.id().toString());
+                return false;
+            }
+            notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_UPDATE,
+                                             vpnPort));
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removePorts(Iterable<VpnPortId> vpnPortIds) {
+        checkNotNull(vpnPortIds, VPN_PORT_NOT_NULL);
+        for (VpnPortId vpnPortid : vpnPortIds) {
+            VpnPort vpnPort = vpnPortStore.get(vpnPortid);
+            vpnPortStore.remove(vpnPortid);
+            if (vpnPortStore.containsKey(vpnPortid)) {
+                log.info(VPN_PORT_DELETE_FAILED, vpnPortid.toString());
+                return false;
+            }
+            notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_DELETE,
+                                             vpnPort));
+        }
+        return true;
+    }
+
+    @Override
+    public void processGluonConfig(String action, String key, JsonNode value) {
+        Collection<VpnPort> vpnPorts;
+        switch (action) {
+            case DELETE:
+                String[] list = key.split(SLASH);
+                VpnPortId vpnPortId
+                        = VpnPortId.vpnPortId(list[list.length - 1]);
+                Set<VpnPortId> vpnPortIds = Sets.newHashSet(vpnPortId);
+                removePorts(vpnPortIds);
+                // After removing vpn port and also remove virtual port from vtn
+                VirtualPortId virtualPortId
+                        = VirtualPortId.portId(list[list.length - 1]);
+                Set<VirtualPortId> virtualPortIds
+                        = Sets.newHashSet(virtualPortId);
+                virtualPortService.removePorts(virtualPortIds);
+                break;
+            case SET:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                vpnPorts = changeJsonToSub(value);
+                createPorts(vpnPorts);
+                break;
+            case UPDATE:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                vpnPorts = changeJsonToSub(value);
+                updatePorts(vpnPorts);
+                break;
+            default:
+                log.info("Invalid action is received while processing VPN " +
+                                 "port configuration");
+        }
+    }
+
+    /**
+     * Creates dummy gluon network to the VTN.
+     *
+     * @param state        the base port state
+     * @param adminStateUp the base port admin status
+     * @param tenantID     the base port tenant ID
+     */
+    private void createDummyGluonNetwork(boolean adminStateUp, String state,
+                                         TenantId tenantID) {
+        String id = "11111111-1111-1111-1111-111111111111";
+        String name = "GluonNetwork";
+        String segmentationID = "50";
+        String physicalNetwork = "None";
+
+        TenantNetwork network = new DefaultTenantNetwork(TenantNetworkId.networkId(id), name,
+                                                         adminStateUp,
+                                                         TenantNetwork.State.valueOf(state),
+                                                         false, tenantID,
+                                                         false,
+                                                         TenantNetwork.Type.LOCAL,
+                                                         PhysicalNetwork.physicalNetwork(physicalNetwork),
+                                                         SegmentationId.segmentationId(segmentationID));
+
+        Set<TenantNetwork> networksSet = Sets.newHashSet(network);
+        tenantNetworkService.createNetworks(networksSet);
+    }
+
+
+    /**
+     * Creates dummy gluon subnet to the VTN.
+     *
+     * @param tenantId the base port tenant ID
+     */
+    public void createDummySubnet(TenantId tenantId) {
+        String id = "22222222-2222-2222-2222-222222222222";
+        String subnetName = "GluonSubnet";
+        String cidr = "0.0.0.0/0";
+        String gatewayIp = "0.0.0.0";
+        Set<HostRoute> hostRoutes = Sets.newHashSet();
+        String ipV6AddressMode = null;
+        String ipV6RaMode = null;
+        TenantNetworkId tenantNetworkId = null;
+        Set<AllocationPool> allocationPools = Sets.newHashSet();
+        Iterable<TenantNetwork> networks
+                = tenantNetworkService.getNetworks();
+
+        for (TenantNetwork tenantNetwork : networks) {
+            if (tenantNetwork.name().equals("GluonNetwork")) {
+                tenantNetworkId = tenantNetwork.id();
+                break;
+            }
+        }
+        Subnet subnet = new DefaultSubnet(SubnetId.subnetId(id), subnetName,
+                                          tenantNetworkId,
+                                          tenantId, IpAddress.Version.INET,
+                                          cidr == null ? null : IpPrefix.valueOf(cidr),
+                                          gatewayIp == null ? null : IpAddress.valueOf(gatewayIp),
+                                          false, false, hostRoutes,
+                                          ipV6AddressMode == null ? null : Subnet.Mode.valueOf(ipV6AddressMode),
+                                          ipV6RaMode == null ? null : Subnet.Mode.valueOf(ipV6RaMode),
+                                          allocationPools);
+
+        Set<Subnet> subnetsSet = Sets.newHashSet(subnet);
+        subnetService.createSubnets(subnetsSet);
+    }
+
+    /**
+     * Returns a collection of vpnPort from subnetNodes.
+     *
+     * @param vpnPortNodes the vpnPort json node
+     * @return list of vpnports
+     */
+    private Collection<VpnPort> changeJsonToSub(JsonNode vpnPortNodes) {
+        checkNotNull(vpnPortNodes, JSON_NOT_NULL);
+        Map<VpnPortId, VpnPort> vpnPortMap = new HashMap<>();
+        String interfaceId = vpnPortNodes.get(INTERFACE_ID).asText();
+        VpnPortId vpnPortId = VpnPortId.vpnPortId(interfaceId);
+        VpnInstanceId vpnInstanceId = VpnInstanceId
+                .vpnInstanceId(vpnPortNodes.get(VPN_INSTANCE).asText());
+        VpnPort vpnPort = new DefaultVpnPort(vpnPortId, vpnInstanceId);
+        vpnPortMap.put(vpnPortId, vpnPort);
+        // update ip address and tenant network information in vtn
+        TenantNetworkId tenantNetworkId = null;
+        Map<VirtualPortId, VirtualPort> vPortMap = new HashMap<>();
+        BasePortId basePortId = BasePortId.portId(interfaceId);
+        VirtualPortId virtualPortId = VirtualPortId.portId(interfaceId);
+        BasePort bPort = basePortService.getPort(basePortId);
+        if (bPort != null) {
+            FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(basePortId.toString()),
+                                              IpAddress.valueOf(vpnPortNodes
+                                                                        .get("ipaddress").asText()));
+            Set<FixedIp> fixedIps = new HashSet<>();
+            fixedIps.add(fixedIp);
+            Map<String, String> strMap = new HashMap<>();
+            boolean adminStateUp = bPort.adminStateUp();
+            strMap.put("name", bPort.name());
+            strMap.put("deviceOwner", bPort.deviceOwner());
+            strMap.put("bindingVnicType", bPort.bindingVnicType());
+            strMap.put("bindingVifType", bPort.bindingVifType());
+            strMap.put("bindingVifDetails", bPort.bindingVifDetails());
+            String state = bPort.state();
+            MacAddress macAddress = bPort.macAddress();
+            TenantId tenantId = bPort.tenantId();
+            DeviceId deviceId = bPort.deviceId();
+            BindingHostId bindingHostId = bPort.bindingHostId();
+            // Creates Dummy Gluon Network and Subnet
+            createDummyGluonNetwork(adminStateUp, state, tenantId);
+            createDummySubnet(tenantId);
+
+            Iterable<TenantNetwork> networks
+                    = tenantNetworkService.getNetworks();
+
+            for (TenantNetwork tenantNetwork : networks) {
+                if (tenantNetwork.name().equals("GluonNetwork")) {
+                    tenantNetworkId = tenantNetwork.id();
+                    break;
+                }
+            }
+            if (tenantNetworkId != null) {
+
+                DefaultVirtualPort vPort = new DefaultVirtualPort(virtualPortId,
+                                                                  tenantNetworkId,
+                                                                  adminStateUp,
+                                                                  strMap, isState(state),
+                                                                  macAddress, tenantId,
+                                                                  deviceId, fixedIps,
+                                                                  bindingHostId,
+                                                                  null,
+                                                                  null);
+                vPortMap.put(virtualPortId, vPort);
+                Collection<VirtualPort> virtualPorts
+                        = Collections.unmodifiableCollection(vPortMap.values());
+                virtualPortService.createPorts(virtualPorts);
+            }
+        }
+
+        return Collections.unmodifiableCollection(vpnPortMap.values());
+    }
+
+    /**
+     * Returns BasePort State.
+     *
+     * @param state the base port state
+     * @return the basePort state
+     */
+    private VirtualPort.State isState(String state) {
+        if (state.equals("ACTIVE")) {
+            return VirtualPort.State.ACTIVE;
+        } else {
+            return VirtualPort.State.DOWN;
+        }
+
+    }
+
+    @Override
+    public void addListener(VpnPortListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeListener(VpnPortListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.remove(listener);
+    }
+
+    /**
+     * Notifies specify event to all listeners.
+     *
+     * @param event Vpn Port event
+     */
+    private void notifyListeners(VpnPortEvent event) {
+        checkNotNull(event, EVENT_NOT_NULL);
+        listeners.forEach(listener -> {
+            listener.event(event);
+        });
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/package-info.java
new file mode 100755
index 0000000..5dc98e9
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * VPN resources that used by l3vpn.
+ */
+package org.onosproject.evpnopenflow.rsc.vpnport.impl;
