diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/EvpnService.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/EvpnService.java
new file mode 100755
index 0000000..560b96e
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/EvpnService.java
@@ -0,0 +1,76 @@
+/*
+ * 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.manager;
+
+import org.onosproject.evpnopenflow.rsc.VpnPort;
+import org.onosproject.incubator.net.routing.EvpnRoute;
+import org.onosproject.net.Host;
+
+/**
+ * Service for interacting with the route and host events.
+ */
+public interface EvpnService {
+    /**
+     * Transfer remote route to private route and set mpls flows out when
+     * BgpRoute update.
+     *
+     * @param route evpn route
+     */
+    void onBgpEvpnRouteUpdate(EvpnRoute route);
+
+    /**
+     * Transfer remote route to private route and delete mpls flows out when
+     * BgpRoute delete.
+     *
+     * @param route evpn route
+     */
+    void onBgpEvpnRouteDelete(EvpnRoute route);
+
+    /**
+     * Get VPN info from EVPN app store and create route, set flows when host
+     * detected.
+     *
+     * @param host host information
+     */
+    void onHostDetected(Host host);
+
+    /**
+     * Get VPN info from EVPN app store and delete route, set flows when
+     * host
+     * vanished.
+     *
+     * @param host host information
+     */
+    void onHostVanished(Host host);
+
+    /**
+     * Get VPN info from EVPN app store and create route, set flows when
+     * host
+     * detected.
+     *
+     * @param vpnPort vpnPort information
+     */
+    void onVpnPortSet(VpnPort vpnPort);
+
+    /**
+     * Get VPN info from EVPN app store and delete route, set flows when host
+     * vanished.
+     *
+     * @param vpnPort vpnPort information
+     */
+    void onVpnPortDelete(VpnPort vpnPort);
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/EvpnManager.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/EvpnManager.java
new file mode 100755
index 0000000..7f7314b
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/EvpnManager.java
@@ -0,0 +1,1132 @@
+/*
+ * 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.manager.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.osgi.DefaultServiceDirectory;
+import org.onlab.packet.EthType;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MplsLabel;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.evpnopenflow.manager.EvpnService;
+import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
+import org.onosproject.evpnopenflow.rsc.VpnInstance;
+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.vpnafconfig.VpnAfConfigEvent;
+import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigListener;
+import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigService;
+import org.onosproject.evpnopenflow.rsc.vpninstance.VpnInstanceService;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortEvent;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortListener;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortService;
+import org.onosproject.gluon.rsc.GluonConfig;
+import org.onosproject.incubator.net.resource.label.LabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourceService;
+import org.onosproject.incubator.net.routing.EvpnInstanceName;
+import org.onosproject.incubator.net.routing.EvpnInstanceNextHop;
+import org.onosproject.incubator.net.routing.EvpnInstancePrefix;
+import org.onosproject.incubator.net.routing.EvpnInstanceRoute;
+import org.onosproject.incubator.net.routing.EvpnNextHop;
+import org.onosproject.incubator.net.routing.EvpnRoute;
+import org.onosproject.incubator.net.routing.EvpnRoute.Source;
+import org.onosproject.incubator.net.routing.EvpnRouteAdminService;
+import org.onosproject.incubator.net.routing.EvpnRouteEvent;
+import org.onosproject.incubator.net.routing.EvpnRouteListener;
+import org.onosproject.incubator.net.routing.EvpnRouteService;
+import org.onosproject.incubator.net.routing.EvpnRouteSet;
+import org.onosproject.incubator.net.routing.EvpnRouteStore;
+import org.onosproject.incubator.net.routing.Label;
+import org.onosproject.incubator.net.routing.RouteDistinguisher;
+import org.onosproject.incubator.net.routing.VpnRouteTarget;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+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.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.Objective.Operation;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type.Reference;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ARP_PRIORITY;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ARP_RESPONSE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BASEPORT;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BGP_EVPN_ROUTE_DELETE_START;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BGP_EVPN_ROUTE_UPDATE_START;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BOTH;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANNOT_FIND_TUNNEL_PORT_DEVICE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANT_FIND_CONTROLLER_DEVICE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANT_FIND_VPN_INSTANCE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANT_FIND_VPN_PORT;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_OPENFLOW_START;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_OPENFLOW_STOP;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EXPORT_EXTCOMMUNITY;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.FAILED_TO_SET_TUNNEL_DST;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.GET_PRIVATE_LABEL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.HOST_DETECT;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.HOST_VANISHED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IFACEID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IFACEID_OF_HOST_IS_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IMPORT_EXTCOMMUNITY;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_EVENT_RECEIVED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_ROUTE_TARGET_TYPE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_TARGET_RECEIVED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.MPLS_OUT_FLOWS;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.NETWORK_CONFIG_EVENT_IS_RECEIVED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.NOT_MASTER_FOR_SPECIFIC_DEVICE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RELEASE_LABEL_FAILED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_ADD_ARP_RULES;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_REMOVE_ARP_RULES;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SWITCH_CHANNEL_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.TUNNEL_DST;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_TARGET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_TARGET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_BIND;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_TARGET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_UNBIND;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VXLAN;
+import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of the EVPN service.
+ */
+@Component(immediate = true)
+@Service
+public class EvpnManager implements EvpnService {
+    private final Logger log = getLogger(getClass());
+    private static final EthType.EtherType ARP_TYPE = EthType.EtherType.ARP;
+
+    protected ApplicationId appId;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected EvpnRouteService evpnRouteService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected EvpnRouteStore evpnRouteStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected EvpnRouteAdminService evpnRouteAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LabelResourceAdminService labelAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LabelResourceService labelService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VpnInstanceService vpnInstanceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DriverService driverService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VpnPortService vpnPortService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VpnAfConfigService vpnAfConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    public Set<EvpnInstanceRoute> evpnInstanceRoutes = new HashSet<>();
+    private final HostListener hostListener = new InnerHostListener();
+    private final VpnPortListener vpnPortListner = new InnerVpnPortListener();
+    private final VpnAfConfigListener vpnAfConfigListener = new
+            InnerVpnAfConfigListener();
+    private final InternalRouteEventListener routeListener = new
+            InternalRouteEventListener();
+
+    private final NetworkConfigListener configListener = new
+            InternalNetworkConfigListener();
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(APP_ID);
+        hostService.addListener(hostListener);
+        vpnPortService.addListener(vpnPortListner);
+        vpnAfConfigService.addListener(vpnAfConfigListener);
+        configService.addListener(configListener);
+        evpnRouteService.addListener(routeListener);
+
+        labelAdminService
+                .createGlobalPool(LabelResourceId.labelResourceId(1),
+                                  LabelResourceId.labelResourceId(1000));
+        log.info(EVPN_OPENFLOW_START);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        hostService.removeListener(hostListener);
+        vpnPortService.removeListener(vpnPortListner);
+        vpnAfConfigService.removeListener(vpnAfConfigListener);
+        configService.removeListener(configListener);
+        log.info(EVPN_OPENFLOW_STOP);
+    }
+
+    @Override
+    public void onBgpEvpnRouteUpdate(EvpnRoute route) {
+        if (EvpnRoute.Source.LOCAL.equals(route.source())) {
+            return;
+        }
+        log.info(BGP_EVPN_ROUTE_UPDATE_START, route);
+        // deal with public route and transfer to private route
+        if (vpnInstanceService.getInstances().isEmpty()) {
+            log.info("unable to get instnaces from vpninstance");
+            return;
+        }
+
+        vpnInstanceService.getInstances().forEach(vpnInstance -> {
+            log.info("got instnaces from vpninstance but not entered here");
+            List<VpnRouteTarget> vpnImportRouteRt = new
+                    LinkedList<>(vpnInstance.getImportRouteTargets());
+            List<VpnRouteTarget> expRt = route.exportRouteTarget();
+            List<VpnRouteTarget> similar = new LinkedList<>(expRt);
+            similar.retainAll(vpnImportRouteRt);
+
+            if (!similar.isEmpty()) {
+                EvpnInstancePrefix evpnPrefix = EvpnInstancePrefix
+                        .evpnPrefix(route.prefixMac(), route.prefixIp());
+
+                EvpnInstanceNextHop evpnNextHop = EvpnInstanceNextHop
+                        .evpnNextHop(route.ipNextHop(), route.label());
+
+                EvpnInstanceRoute evpnPrivateRoute = new
+                        EvpnInstanceRoute(vpnInstance.vpnInstanceName(),
+                                          route.routeDistinguisher(),
+                                          vpnImportRouteRt,
+                                          route.exportRouteTarget(),
+                                          evpnPrefix,
+                                          evpnNextHop,
+                                          route.prefixIp(),
+                                          route.ipNextHop(),
+                                          route.label());
+
+                //update route in route subsystem
+                //TODO: added by shahid
+                evpnInstanceRoutes.add(evpnPrivateRoute);
+
+            }
+        });
+
+        deviceService.getAvailableDevices(Device.Type.SWITCH)
+                .forEach(device -> {
+                    log.info("switch device is found");
+                    Set<Host> hosts = getHostsByVpn(device, route);
+                    for (Host h : hosts) {
+                        addArpFlows(device.id(),
+                                    route,
+                                    Objective.Operation.ADD,
+                                    h);
+                        ForwardingObjective.Builder objective =
+                                getMplsOutBuilder(device.id(),
+                                                  route,
+                                                  h);
+                        log.info(MPLS_OUT_FLOWS, h);
+                        flowObjectiveService.forward(device.id(),
+                                                     objective.add());
+                    }
+                });
+        log.info("no switch device is found");
+    }
+
+    @Override
+    public void onBgpEvpnRouteDelete(EvpnRoute route) {
+        if (EvpnRoute.Source.LOCAL.equals(route.source())) {
+            return;
+        }
+        log.info(BGP_EVPN_ROUTE_DELETE_START, route);
+        // deal with public route deleted and transfer to private route
+        vpnInstanceService.getInstances().forEach(vpnInstance -> {
+            List<VpnRouteTarget> vpnRouteRt = new
+                    LinkedList<>(vpnInstance.getImportRouteTargets());
+            List<VpnRouteTarget> localRt = route.exportRouteTarget();
+            List<VpnRouteTarget> similar = new LinkedList<>(localRt);
+            similar.retainAll(vpnRouteRt);
+
+            if (!similar.isEmpty()) {
+                EvpnInstancePrefix evpnPrefix = EvpnInstancePrefix
+                        .evpnPrefix(route.prefixMac(), route.prefixIp());
+
+                EvpnInstanceNextHop evpnNextHop = EvpnInstanceNextHop
+                        .evpnNextHop(route.ipNextHop(), route.label());
+
+                EvpnInstanceRoute evpnPrivateRoute = new
+                        EvpnInstanceRoute(vpnInstance.vpnInstanceName(),
+                                          route.routeDistinguisher(),
+                                          vpnRouteRt,
+                                          route.exportRouteTarget(),
+                                          evpnPrefix,
+                                          evpnNextHop,
+                                          route.prefixIp(),
+                                          route.ipNextHop(),
+                                          route.label());
+                //TODO: Added by Shahid
+                //evpnRouteAdminService.withdraw(Sets.newHashSet
+                //       (evpnPrivateRoute));
+
+            }
+        });
+        deviceService.getAvailableDevices(Device.Type.SWITCH)
+                .forEach(device -> {
+                    Set<Host> hosts = getHostsByVpn(device, route);
+                    for (Host h : hosts) {
+                        addArpFlows(device.id(),
+                                    route,
+                                    Objective.Operation.REMOVE,
+                                    h);
+                        ForwardingObjective.Builder objective
+                                = getMplsOutBuilder(device.id(),
+                                                    route,
+                                                    h);
+                        flowObjectiveService.forward(device.id(),
+                                                     objective.remove());
+                    }
+                });
+    }
+
+    private void addArpFlows(DeviceId deviceId,
+                             EvpnRoute route,
+                             Operation type,
+                             Host host) {
+        DriverHandler handler = driverService.createHandler(deviceId);
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(ARP_TYPE.ethType().toShort())
+                .matchArpTpa(route.prefixIp().address().getIp4Address())
+                .matchInPort(host.location().port()).build();
+
+        ExtensionTreatmentResolver resolver = handler
+                .behaviour(ExtensionTreatmentResolver.class);
+        ExtensionTreatment ethSrcToDst = resolver
+                .getExtensionInstruction(ExtensionTreatmentType
+                                                 .ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_ETH_SRC_TO_DST
+                                                 .type());
+        ExtensionTreatment arpShaToTha = resolver
+                .getExtensionInstruction(ExtensionTreatmentType
+                                                 .ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_ARP_SHA_TO_THA
+                                                 .type());
+        ExtensionTreatment arpSpaToTpa = resolver
+                .getExtensionInstruction(ExtensionTreatmentType
+                                                 .ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_ARP_SPA_TO_TPA
+                                                 .type());
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .extension(ethSrcToDst, deviceId).setEthSrc(route.prefixMac())
+                .setArpOp(ARP_RESPONSE).extension(arpShaToTha, deviceId)
+                .extension(arpSpaToTpa, deviceId).setArpSha(route.prefixMac())
+                .setArpSpa(route.prefixIp().address().getIp4Address())
+                .setOutput(PortNumber.IN_PORT)
+                .build();
+
+        ForwardingObjective.Builder objective = DefaultForwardingObjective
+                .builder().withTreatment(treatment).withSelector(selector)
+                .fromApp(appId).withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .withPriority(ARP_PRIORITY);
+        if (type.equals(Objective.Operation.ADD)) {
+            log.info(ROUTE_ADD_ARP_RULES);
+            flowObjectiveService.forward(deviceId, objective.add());
+        } else {
+            log.info(ROUTE_REMOVE_ARP_RULES);
+            flowObjectiveService.forward(deviceId, objective.remove());
+        }
+    }
+
+    private Set<Host> getHostsByVpn(Device device, EvpnRoute route) {
+        Set<Host> vpnHosts = Sets.newHashSet();
+        Set<Host> hosts = hostService.getConnectedHosts(device.id());
+        for (Host h : hosts) {
+            String ifaceId = h.annotations().value(IFACEID);
+            if (!vpnPortService.exists(VpnPortId.vpnPortId(ifaceId))) {
+                continue;
+            }
+
+            VpnPort vpnPort = vpnPortService
+                    .getPort(VpnPortId.vpnPortId(ifaceId));
+            VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
+
+            VpnInstance vpnInstance = vpnInstanceService
+                    .getInstance(vpnInstanceId);
+
+            List<VpnRouteTarget> expRt = route.exportRouteTarget();
+            List<VpnRouteTarget> similar = new LinkedList<>(expRt);
+            similar.retainAll(vpnInstance.getImportRouteTargets());
+            //TODO: currently checking for RT comparision.
+            //TODO: Need to check about RD comparision is really required.
+            //if (route.routeDistinguisher()
+            //.equals(vpnInstance.routeDistinguisher())) {
+            if (!similar.isEmpty()) {
+                vpnHosts.add(h);
+            }
+        }
+        return vpnHosts;
+    }
+
+    private ForwardingObjective.Builder getMplsOutBuilder(DeviceId deviceId,
+                                                          EvpnRoute route,
+                                                          Host h) {
+        DriverHandler handler = driverService.createHandler(deviceId);
+        ExtensionTreatmentResolver resolver = handler
+                .behaviour(ExtensionTreatmentResolver.class);
+        ExtensionTreatment treatment = resolver
+                .getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
+        try {
+            treatment.setPropertyValue(TUNNEL_DST, route.ipNextHop());
+        } catch (Exception e) {
+            log.error(FAILED_TO_SET_TUNNEL_DST, deviceId);
+        }
+        TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
+        builder.extension(treatment, deviceId);
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(h.location().port()).matchEthSrc(h.mac())
+                .matchEthDst(route.prefixMac()).build();
+
+        TrafficTreatment build = builder.pushMpls()
+                .setMpls(MplsLabel.mplsLabel(route.label().getLabel()))
+                .setOutput(getTunnlePort(deviceId)).build();
+
+        return DefaultForwardingObjective
+                .builder().withTreatment(build).withSelector(selector)
+                .fromApp(appId).withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .withPriority(60000);
+
+    }
+
+    private ForwardingObjective.Builder getMplsInBuilder(DeviceId deviceId,
+                                                         Host host,
+                                                         Label label) {
+        TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(getTunnlePort(deviceId))
+                .matchEthType(EthType.EtherType.MPLS_UNICAST.ethType()
+                                      .toShort())
+                .matchMplsBos(true)
+                .matchMplsLabel(MplsLabel.mplsLabel(label.getLabel())).build();
+        TrafficTreatment treatment = builder.popMpls(EthType
+                                                             .EtherType
+                                                             .IPV4.ethType())
+                .setOutput(host.location().port()).build();
+        return DefaultForwardingObjective
+                .builder().withTreatment(treatment).withSelector(selector)
+                .fromApp(appId).withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .withPriority(60000);
+    }
+
+    /**
+     * Get local tunnel ports.
+     *
+     * @param ports Iterable of Port
+     * @return Collection of PortNumber
+     */
+    private Collection<PortNumber> getLocalTunnelPorts(Iterable<Port>
+                                                               ports) {
+        Collection<PortNumber> localTunnelPorts = new ArrayList<>();
+        if (ports != null) {
+            log.info("port value is not null {}", ports);
+            Sets.newHashSet(ports).stream()
+                    .filter(p -> !p.number().equals(PortNumber.LOCAL))
+                    .forEach(p -> {
+                        log.info("number is not matched but no vxlan port");
+                        if (p.annotations().value(AnnotationKeys.PORT_NAME)
+                                .startsWith(VXLAN)) {
+                            localTunnelPorts.add(p.number());
+                        }
+                    });
+        }
+        return localTunnelPorts;
+    }
+
+    private PortNumber getTunnlePort(DeviceId deviceId) {
+        Iterable<Port> ports = deviceService.getPorts(deviceId);
+        Collection<PortNumber> localTunnelPorts = getLocalTunnelPorts(ports);
+        if (localTunnelPorts.isEmpty()) {
+            log.error(CANNOT_FIND_TUNNEL_PORT_DEVICE, deviceId);
+            return null;
+        }
+        return localTunnelPorts.iterator().next();
+    }
+
+    private void setFlows(DeviceId deviceId, Host host, Label label,
+                          List<VpnRouteTarget> rtImport,
+                          Operation type) {
+        log.info("Set the flows to OVS");
+        ForwardingObjective.Builder objective = getMplsInBuilder(deviceId,
+                                                                 host,
+                                                                 label);
+        if (type.equals(Objective.Operation.ADD)) {
+            flowObjectiveService.forward(deviceId, objective.add());
+        } else {
+            flowObjectiveService.forward(deviceId, objective.remove());
+        }
+
+        // download remote flows if and only routes are present.
+        evpnRouteStore.getRouteTables().forEach(routeTableId -> {
+            Collection<EvpnRouteSet> routes
+                    = evpnRouteStore.getRoutes(routeTableId);
+            if (routes != null) {
+                routes.forEach(route -> {
+                    Collection<EvpnRoute> evpnRoutes = route.routes();
+                    for (EvpnRoute evpnRoute : evpnRoutes) {
+                        EvpnRoute evpnRouteTem = evpnRoute;
+                        Set<Host> hostByMac = hostService
+                                .getHostsByMac(evpnRouteTem
+                                                       .prefixMac());
+
+                        if (!hostByMac.isEmpty()
+                                || (!(compareLists(rtImport, evpnRouteTem
+                                .exportRouteTarget())))) {
+                            log.info("Route target import/export is not matched");
+                            continue;
+                        }
+                        log.info("Set the ARP flows");
+                        addArpFlows(deviceId, evpnRouteTem, type, host);
+                        ForwardingObjective.Builder build = getMplsOutBuilder(deviceId,
+                                                                              evpnRouteTem,
+                                                                              host);
+                        log.info("Set the MPLS  flows");
+                        if (type.equals(Objective.Operation.ADD)) {
+                            flowObjectiveService.forward(deviceId, build.add());
+                        } else {
+                            flowObjectiveService.forward(deviceId, build.remove());
+                        }
+                    }
+                });
+            }
+        });
+    }
+
+    /**
+     * comparison for tow lists.
+     *
+     * @param list1 import list
+     * @param list2 export list
+     * @return true or false
+     */
+    public static boolean compareLists(List<VpnRouteTarget> list1,
+                                       List<VpnRouteTarget> list2) {
+        if (list1 == null && list2 == null) {
+            return true;
+        }
+
+        if (list1 != null && list2 != null) {
+            if (list1.size() == list2.size()) {
+                for (VpnRouteTarget li1Long : list1) {
+                    boolean isEqual = false;
+                    for (VpnRouteTarget li2Long : list2) {
+                        if (li1Long.equals(li2Long)) {
+                            isEqual = true;
+                            break;
+                        }
+                    }
+                    if (!isEqual) {
+                        return false;
+                    }
+                }
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public void onHostDetected(Host host) {
+        log.info(HOST_DETECT, host);
+        DeviceId deviceId = host.location().deviceId();
+        if (!mastershipService.isLocalMaster(deviceId)) {
+            log.info(NOT_MASTER_FOR_SPECIFIC_DEVICE);
+            return;
+        }
+
+        String ifaceId = host.annotations().value(IFACEID);
+        if (ifaceId == null) {
+            log.error(IFACEID_OF_HOST_IS_NULL);
+            return;
+        }
+        VpnPortId vpnPortId = VpnPortId.vpnPortId(ifaceId);
+        // Get VPN port id from EVPN app store
+        if (!vpnPortService.exists(vpnPortId)) {
+            log.info(CANT_FIND_VPN_PORT, ifaceId);
+            return;
+        }
+
+        VpnPort vpnPort = vpnPortService.getPort(vpnPortId);
+        VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
+        if (!vpnInstanceService.exists(vpnInstanceId)) {
+            log.info(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
+            return;
+        }
+
+        Label privateLabel = applyLabel();
+        // create private route and get label
+        setPrivateRoute(host, vpnInstanceId, privateLabel,
+                        Objective.Operation.ADD);
+        VpnInstance vpnInstance = vpnInstanceService.getInstance(vpnInstanceId);
+
+        List<VpnRouteTarget> rtImport
+                = new LinkedList<>(vpnInstance.getImportRouteTargets());
+        List<VpnRouteTarget> rtExport
+                = new LinkedList<>(vpnInstance.getExportRouteTargets());
+        //download flows
+        setFlows(deviceId, host, privateLabel, rtImport,
+                 Objective.Operation.ADD);
+    }
+
+    /**
+     * update or withdraw evpn route from route admin service.
+     *
+     * @param host          host
+     * @param vpnInstanceId vpn instance id
+     * @param privateLabel  private label
+     * @param type          operation type
+     */
+    private void setPrivateRoute(Host host, VpnInstanceId vpnInstanceId,
+                                 Label privateLabel,
+                                 Operation type) {
+        DeviceId deviceId = host.location().deviceId();
+        Device device = deviceService.getDevice(deviceId);
+        VpnInstance vpnInstance = vpnInstanceService.getInstance(vpnInstanceId);
+        RouteDistinguisher rd = vpnInstance.routeDistinguisher();
+        Set<VpnRouteTarget> importRouteTargets
+                = vpnInstance.getImportRouteTargets();
+        Set<VpnRouteTarget> exportRouteTargets
+                = vpnInstance.getExportRouteTargets();
+        EvpnInstanceName instanceName = vpnInstance.vpnInstanceName();
+        String url = device.annotations().value(SWITCH_CHANNEL_ID);
+        String controllerIp = url.substring(0, url.lastIndexOf(":"));
+
+        if (controllerIp == null) {
+            log.error(CANT_FIND_CONTROLLER_DEVICE, device.id().toString());
+            return;
+        }
+        IpAddress ipAddress = IpAddress.valueOf(controllerIp);
+        // create private route
+        EvpnInstanceNextHop evpnNextHop = EvpnInstanceNextHop
+                .evpnNextHop(ipAddress, privateLabel);
+        EvpnInstancePrefix evpnPrefix = EvpnInstancePrefix
+                .evpnPrefix(host.mac(), IpPrefix.valueOf(host.ipAddresses()
+                                                                 .iterator()
+                                                                 .next()
+                                                                 .getIp4Address(), 32));
+        EvpnInstanceRoute evpnPrivateRoute
+                = new EvpnInstanceRoute(instanceName,
+                                        rd,
+                                        new LinkedList<>(importRouteTargets),
+                                        new LinkedList<>(exportRouteTargets),
+                                        evpnPrefix,
+                                        evpnNextHop,
+                                        IpPrefix.valueOf(host.ipAddresses()
+                                                                 .iterator()
+                                                                 .next()
+                                                                 .getIp4Address(), 32),
+                                        ipAddress,
+                                        privateLabel);
+
+        // change to public route
+        EvpnRoute evpnRoute
+                = new EvpnRoute(Source.LOCAL,
+                                host.mac(),
+                                IpPrefix.valueOf(host.ipAddresses()
+                                                         .iterator()
+                                                         .next()
+                                                         .getIp4Address(), 32),
+                                ipAddress,
+                                rd,
+                                new LinkedList<>(importRouteTargets),
+                                new LinkedList<>(exportRouteTargets),
+                                privateLabel);
+        if (type.equals(Objective.Operation.ADD)) {
+            //evpnRouteAdminService.update(Sets.newHashSet(evpnPrivateRoute));
+            evpnInstanceRoutes.add(evpnPrivateRoute);
+            evpnRouteAdminService.update(Sets.newHashSet(evpnRoute));
+
+        } else {
+            //evpnRouteAdminService.withdraw(Sets.newHashSet(evpnPrivateRoute));
+            evpnInstanceRoutes.remove(evpnPrivateRoute);
+            evpnRouteAdminService.withdraw(Sets.newHashSet(evpnRoute));
+        }
+    }
+
+    /**
+     * Generate the label for evpn route from global pool.
+     */
+    private Label applyLabel() {
+        Collection<LabelResource> privateLabels = labelService
+                .applyFromGlobalPool(1);
+        Label privateLabel = Label.label(0);
+        if (!privateLabels.isEmpty()) {
+            privateLabel = Label.label(Integer.parseInt(
+                    privateLabels.iterator().next()
+                            .labelResourceId().toString()));
+        }
+        log.info(GET_PRIVATE_LABEL, privateLabel);
+        return privateLabel;
+    }
+
+    @Override
+    public void onHostVanished(Host host) {
+        log.info(HOST_VANISHED, host);
+        DeviceId deviceId = host.location().deviceId();
+        if (!mastershipService.isLocalMaster(deviceId)) {
+            return;
+        }
+        String ifaceId = host.annotations().value(IFACEID);
+        if (ifaceId == null) {
+            log.error(IFACEID_OF_HOST_IS_NULL);
+            return;
+        }
+        // Get info from Gluon Shim
+        VpnPort vpnPort = vpnPortService.getPort(VpnPortId.vpnPortId(ifaceId));
+        VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
+        if (!vpnInstanceService.exists(vpnInstanceId)) {
+            log.info(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
+            return;
+        }
+        VpnInstance vpnInstance = vpnInstanceService.getInstance(vpnInstanceId);
+
+        Label label = releaseLabel(vpnInstance, host);
+        // create private route and get label
+        setPrivateRoute(host, vpnInstanceId, label, Objective.Operation.REMOVE);
+        // download flows
+        List<VpnRouteTarget> rtImport
+                = new LinkedList<>(vpnInstance.getImportRouteTargets());
+        List<VpnRouteTarget> rtExport
+                = new LinkedList<>(vpnInstance.getExportRouteTargets());
+        setFlows(deviceId, host, label, rtImport,
+                 Objective.Operation.REMOVE);
+    }
+
+    /**
+     * Release the label from the evpn route.
+     *
+     * @param vpnInstance vpn instance
+     * @param host        host
+     */
+    private Label releaseLabel(VpnInstance vpnInstance, Host host) {
+        EvpnInstanceName instanceName = vpnInstance.vpnInstanceName();
+
+        //Get all vpn-instance routes and check for label.
+        Label label = null;
+        for (EvpnInstanceRoute evpnInstanceRoute : evpnInstanceRoutes) {
+            if (evpnInstanceRoute.evpnInstanceName().equals(instanceName)) {
+                label = evpnInstanceRoute.getLabel();
+                // delete private route and get label ,change to public route
+                boolean isRelease
+                        = labelService
+                        .releaseToGlobalPool(
+                                Sets.newHashSet(
+                                        LabelResourceId
+                                                .labelResourceId(label.getLabel())));
+                if (!isRelease) {
+                    log.error(RELEASE_LABEL_FAILED, label.getLabel());
+                }
+                break;
+            }
+        }
+        return label;
+    }
+
+    private class InternalRouteEventListener implements EvpnRouteListener {
+
+        @Override
+        public void event(EvpnRouteEvent event) {
+            if (!(event.subject() instanceof EvpnRoute)) {
+                return;
+            }
+            EvpnRoute route = (EvpnRoute) event.subject();
+            if (EvpnRouteEvent.Type.ROUTE_ADDED == event.type()) {
+                onBgpEvpnRouteUpdate(route);
+            } else if (EvpnRouteEvent.Type.ROUTE_REMOVED == event.type()) {
+                onBgpEvpnRouteDelete(route);
+            }
+        }
+    }
+
+    private class InnerHostListener implements HostListener {
+
+        @Override
+        public void event(HostEvent event) {
+            Host host = event.subject();
+            if (HostEvent.Type.HOST_ADDED == event.type()) {
+                onHostDetected(host);
+            } else if (HostEvent.Type.HOST_REMOVED == event.type()) {
+                onHostVanished(host);
+            }
+        }
+
+    }
+
+    private class InnerVpnPortListener implements VpnPortListener {
+
+        @Override
+        public void event(VpnPortEvent event) {
+            VpnPort vpnPort = event.subject();
+            if (VpnPortEvent.Type.VPN_PORT_DELETE == event.type()) {
+                onVpnPortDelete(vpnPort);
+            } else if (VpnPortEvent.Type.VPN_PORT_SET == event.type()) {
+                onVpnPortSet(vpnPort);
+            }
+        }
+    }
+
+    @Override
+    public void onVpnPortDelete(VpnPort vpnPort) {
+        // delete the flows of this vpn
+        hostService.getHosts().forEach(host -> {
+            VpnPortId vpnPortId = vpnPort.id();
+            VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
+            if (!vpnInstanceService.exists(vpnInstanceId)) {
+                log.error(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
+                return;
+            }
+            VpnInstance vpnInstance = vpnInstanceService
+                    .getInstance(vpnInstanceId);
+            List<VpnRouteTarget> rtImport
+                    = new LinkedList<>(vpnInstance.getImportRouteTargets());
+            List<VpnRouteTarget> rtExport
+                    = new LinkedList<>(vpnInstance.getExportRouteTargets());
+
+            if (vpnPortId.vpnPortId()
+                    .equals(host.annotations().value(IFACEID))) {
+                log.info(VPN_PORT_UNBIND);
+                Label label = releaseLabel(vpnInstance, host);
+                // create private route and get label
+                DeviceId deviceId = host.location().deviceId();
+                setPrivateRoute(host, vpnInstanceId, label,
+                                Objective.Operation.REMOVE);
+                // download flows
+                setFlows(deviceId, host, label, rtImport,
+                         Objective.Operation.REMOVE);
+            }
+        });
+    }
+
+    @Override
+    public void onVpnPortSet(VpnPort vpnPort) {
+        // delete the flows of this vpn
+        hostService.getHosts().forEach(host -> {
+            VpnPortId vpnPortId = vpnPort.id();
+            VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
+            VpnInstance vpnInstance = vpnInstanceService
+                    .getInstance(vpnInstanceId);
+            if (vpnInstance == null) {
+                log.info("why vpn instance is null");
+                return;
+            }
+            List<VpnRouteTarget> rtImport
+                    = new LinkedList<>(vpnInstance.getImportRouteTargets());
+/*            List<VpnRouteTarget> rtExport
+                    = new LinkedList<>(vpnInstance.getExportRouteTargets());*/
+
+            if (!vpnInstanceService.exists(vpnInstanceId)) {
+                log.error(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
+                return;
+            }
+
+            if (vpnPortId.vpnPortId()
+                    .equals(host.annotations().value(IFACEID))) {
+                log.info(VPN_PORT_BIND);
+                Label label = applyLabel();
+                // create private route and get label
+                DeviceId deviceId = host.location().deviceId();
+                setPrivateRoute(host, vpnInstanceId, label,
+                                Objective.Operation.ADD);
+                // download flows
+                setFlows(deviceId, host, label, rtImport,
+                         Objective.Operation.ADD);
+            }
+        });
+    }
+
+    /**
+     * process the gluon configuration and will update the configuration into
+     * vpn port service.
+     *
+     * @param action action
+     * @param key    key
+     * @param value  json node
+     */
+    private void processEtcdResponse(String action, String key, JsonNode
+            value) {
+        String[] list = key.split(SLASH);
+        String target = list[list.length - 2];
+        switch (target) {
+            case VPN_INSTANCE_TARGET:
+                VpnInstanceService vpnInstanceService
+                        = DefaultServiceDirectory
+                        .getService(VpnInstanceService.class);
+                vpnInstanceService.processGluonConfig(action, key, value);
+                break;
+            case VPN_PORT_TARGET:
+                VpnPortService vpnPortService = DefaultServiceDirectory
+                        .getService(VpnPortService.class);
+                vpnPortService.processGluonConfig(action, key, value);
+                break;
+            case VPN_AF_TARGET:
+                VpnAfConfigService vpnAfConfigService =
+                        DefaultServiceDirectory.getService(VpnAfConfigService
+                                                                   .class);
+                vpnAfConfigService.processGluonConfig(action, key, value);
+                break;
+            case BASEPORT:
+                BasePortService basePortService =
+                        DefaultServiceDirectory.getService(BasePortService
+                                                                   .class);
+                basePortService.processGluonConfig(action, key, value);
+                break;
+            default:
+                log.info("why target type is invalid {}", target);
+                log.info(INVALID_TARGET_RECEIVED);
+                break;
+        }
+    }
+
+    /**
+     * parse the gluon configuration received from network config system.
+     *
+     * @param jsonNode json node
+     * @param key      key
+     * @param action   action
+     */
+    private void parseEtcdResponse(JsonNode jsonNode,
+                                   String key,
+                                   String action) {
+        JsonNode modifyValue = null;
+        if (action.equals(SET)) {
+            modifyValue = jsonNode.get(key);
+        }
+        processEtcdResponse(action, key, modifyValue);
+    }
+
+    /**
+     * Listener for network config events.
+     */
+    private class InternalNetworkConfigListener implements
+            NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            String subject;
+            log.info(NETWORK_CONFIG_EVENT_IS_RECEIVED, event.type());
+            if (!event.configClass().equals(GluonConfig.class)) {
+                return;
+            }
+            log.info("Event is received from network configuration {}", event
+                    .type());
+            switch (event.type()) {
+                case CONFIG_UPDATED:
+                    subject = (String) event.subject();
+                    GluonConfig gluonConfig = configService
+                            .getConfig(subject, GluonConfig.class);
+                    JsonNode jsonNode = gluonConfig.node();
+                    parseEtcdResponse(jsonNode, subject, SET);
+                    break;
+                case CONFIG_REMOVED:
+                    subject = (String) event.subject();
+                    parseEtcdResponse(null, subject, DELETE);
+                    break;
+                default:
+                    log.info(INVALID_EVENT_RECEIVED);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * update import and export route target information in route admin service.
+     *
+     * @param evpnInstanceName   evpn instance name
+     * @param exportRouteTargets export route targets
+     * @param importRouteTargets import route targets
+     * @param action             action holds update or delete
+     */
+    private void updateImpExpRtInRoute(EvpnInstanceName evpnInstanceName,
+                                       Set<VpnRouteTarget> exportRouteTargets,
+                                       Set<VpnRouteTarget> importRouteTargets,
+                                       String action) {
+
+        for (EvpnInstanceRoute evpnInstanceRoute : evpnInstanceRoutes) {
+            if (evpnInstanceRoute.evpnInstanceName().equals(evpnInstanceName)) {
+                evpnInstanceRoute
+                        .setExportRtList(new LinkedList<>(exportRouteTargets));
+                evpnInstanceRoute
+                        .setImportRtList(new LinkedList<>(importRouteTargets));
+                if (action.equals(UPDATE)) {
+                    evpnInstanceRoutes.add(evpnInstanceRoute);
+                } else if (action.equals(DELETE)) {
+                    evpnInstanceRoutes.remove(evpnInstanceRoute);
+                }
+                //Get the public route and update route targets.
+                EvpnNextHop evpnNextHop = EvpnNextHop
+                        .evpnNextHop(evpnInstanceRoute.getNextHopl(),
+                                     evpnInstanceRoute.importRouteTarget(),
+                                     evpnInstanceRoute.exportRouteTarget(),
+                                     evpnInstanceRoute.getLabel());
+                Collection<EvpnRoute> evpnPublicRoutes
+                        = evpnRouteStore.getRoutesForNextHop(evpnNextHop.nextHop());
+                for (EvpnRoute pubRoute : evpnPublicRoutes) {
+                    EvpnRoute evpnPubRoute = pubRoute;
+                    if (evpnPubRoute.label().equals(evpnInstanceRoute
+                                                            .getLabel())) {
+                        evpnPubRoute
+                                .setExportRtList(new LinkedList<>(exportRouteTargets));
+                        evpnPubRoute
+                                .setImportRtList(new LinkedList<>(importRouteTargets));
+                        if (action.equals(UPDATE)) {
+                            evpnRouteAdminService.update(Sets.newHashSet(evpnPubRoute));
+                        } else if (action.equals(DELETE)) {
+                            evpnRouteAdminService
+                                    .withdraw(Sets.newHashSet(evpnPubRoute));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * update or withdraw evpn route based on vpn af configuration.
+     *
+     * @param vpnAfConfig vpn af configuration
+     * @param action      action holds update or delete
+     */
+
+    private void processEvpnRouteUpdate(VpnAfConfig vpnAfConfig,
+                                        String action) {
+        Collection<VpnInstance> instances
+                = vpnInstanceService.getInstances();
+        for (VpnInstance vpnInstance : instances) {
+            Set<VpnRouteTarget> configRouteTargets
+                    = vpnInstance.getConfigRouteTargets();
+            for (VpnRouteTarget vpnRouteTarget : configRouteTargets) {
+                if (vpnRouteTarget.equals(vpnAfConfig.routeTarget())) {
+                    Set<VpnRouteTarget> exportRouteTargets
+                            = vpnInstance.getExportRouteTargets();
+                    Set<VpnRouteTarget> importRouteTargets
+                            = vpnInstance.getImportRouteTargets();
+                    String routeTargetType = vpnAfConfig.routeTargetType();
+                    if (action.equals(UPDATE)) {
+                        vpnInstanceService
+                                .updateImpExpRouteTargets(routeTargetType,
+                                                          exportRouteTargets,
+                                                          importRouteTargets,
+                                                          vpnRouteTarget);
+                    } else if (action.equals(DELETE)) {
+                        switch (routeTargetType) {
+                            case EXPORT_EXTCOMMUNITY:
+                                exportRouteTargets.remove(vpnRouteTarget);
+                                break;
+                            case IMPORT_EXTCOMMUNITY:
+                                importRouteTargets.remove(vpnRouteTarget);
+                                break;
+                            case BOTH:
+                                exportRouteTargets.remove(vpnRouteTarget);
+                                importRouteTargets.remove(vpnRouteTarget);
+                                break;
+                            default:
+                                log.info(INVALID_ROUTE_TARGET_TYPE);
+                                break;
+                        }
+                    }
+                    updateImpExpRtInRoute(vpnInstance.vpnInstanceName(),
+                                          exportRouteTargets,
+                                          importRouteTargets,
+                                          action);
+                }
+            }
+        }
+    }
+
+    private class InnerVpnAfConfigListener implements VpnAfConfigListener {
+
+        @Override
+        public void event(VpnAfConfigEvent event) {
+            VpnAfConfig vpnAfConfig = event.subject();
+            if (VpnAfConfigEvent.Type.VPN_AF_CONFIG_DELETE == event.type()) {
+                processEvpnRouteUpdate(vpnAfConfig, DELETE);
+            } else if (VpnAfConfigEvent.Type.VPN_AF_CONFIG_SET
+                    == event.type() || VpnAfConfigEvent.Type
+                    .VPN_AF_CONFIG_UPDATE == event.type()) {
+                processEvpnRouteUpdate(vpnAfConfig, UPDATE);
+            }
+        }
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/package-info.java
new file mode 100755
index 0000000..8f83161
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * EVPN application that process configuration and host, vpn-port, route
+ * events.
+ */
+package org.onosproject.evpnopenflow.manager.impl;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/package-info.java
new file mode 100755
index 0000000..d93de24
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * EVPN application that process configuration and host, vpn-port, route
+ * events.
+ */
+package org.onosproject.evpnopenflow.manager;
