[ONOS] Cherry picked from master 1.7

Change-Id: I74a0c1634f9c425af2bcb646edc3d9170b3c087c
diff --git a/providers/bgp/pom.xml b/providers/bgp/pom.xml
old mode 100755
new mode 100644
index e758768..572e9e4
--- a/providers/bgp/pom.xml
+++ b/providers/bgp/pom.xml
@@ -40,6 +40,11 @@
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
+            <artifactId>onos-incubator-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
             <artifactId>onos-api</artifactId>
             <classifier>tests</classifier>
             <scope>test</scope>
diff --git a/providers/bgp/topology/BUCK b/providers/bgp/topology/BUCK
index 657ed56..ee79b20 100644
--- a/providers/bgp/topology/BUCK
+++ b/providers/bgp/topology/BUCK
@@ -3,6 +3,7 @@
     '//protocols/bgp/api:onos-protocols-bgp-api',
     '//protocols/bgp/bgpio:onos-protocols-bgp-bgpio',
     '//incubator/store:onos-incubator-store',
+    '//incubator/api:onos-incubator-api',
 ]
 
 TEST_DEPS = [
diff --git a/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java b/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java
index 0ac494c..be90682 100644
--- a/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java
+++ b/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java
@@ -17,11 +17,16 @@
 import static org.onosproject.net.DeviceId.deviceId;
 import static org.onosproject.net.Device.Type.ROUTER;
 import static org.onosproject.net.Device.Type.VIRTUAL;
+import static org.onosproject.incubator.net.resource.label.LabelResourceId.labelResourceId;
+import static java.util.stream.Collectors.toList;
 
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 
 import org.onlab.packet.ChassisId;
+import org.onlab.packet.Ip4Address;
+import org.onlab.util.Bandwidth;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -45,9 +50,21 @@
 import org.onosproject.bgpio.types.IsIsNonPseudonode;
 import org.onosproject.bgpio.types.IsIsPseudonode;
 import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
+import org.onosproject.bgpio.types.LinkStateAttributes;
 import org.onosproject.bgpio.types.OspfNonPseudonode;
 import org.onosproject.bgpio.types.OspfPseudonode;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeIsIsAreaId;
+import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrIgpMetric;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrMaxLinkBandwidth;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
 import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipListener;
+import org.onosproject.mastership.MastershipService;
 import org.onosproject.net.AnnotationKeys;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultAnnotations;
@@ -56,12 +73,15 @@
 import org.onosproject.net.Link;
 import org.onosproject.net.MastershipRole;
 import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DefaultPortDescription;
 import org.onosproject.net.device.DeviceDescription;
 import org.onosproject.net.device.DeviceProvider;
 import org.onosproject.net.device.DeviceProviderRegistry;
 import org.onosproject.net.device.DeviceProviderService;
 import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.PortDescription;
 import org.onosproject.net.link.DefaultLinkDescription;
 import org.onosproject.net.link.LinkDescription;
 import org.onosproject.net.link.LinkProvider;
@@ -70,6 +90,7 @@
 import org.onosproject.net.link.LinkService;
 import org.onosproject.net.provider.AbstractProvider;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.config.basics.BandwidthCapacity;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -106,16 +127,39 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LabelResourceAdminService labelResourceAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService networkConfigService;
+
     private DeviceProviderService deviceProviderService;
     private LinkProviderService linkProviderService;
 
+    private InternalMastershipListener masterListener = new InternalMastershipListener();
     private InternalBgpProvider listener = new InternalBgpProvider();
     private static final String UNKNOWN = "unknown";
     public static final long IDENTIFIER_SET = 0x100000000L;
     public static final String AS_NUMBER = "asNumber";
     public static final String DOMAIN_IDENTIFIER = "domainIdentifier";
     public static final String ROUTING_UNIVERSE = "routingUniverse";
+
+    public static final String EXTERNAL_BIT = "externalBit";
+    public static final String ABR_BIT = "abrBit";
+    public static final String INTERNAL_BIT = "internalBit";
+    public static final String PSEUDO = "psuedo";
+    public static final String AREAID = "areaId";
+    public static final String LSRID = "lsrId";
+    public static final String COST = "cost";
+    public static final String TE_COST = "teCost";
+
     public static final long PSEUDO_PORT = 0xffffffff;
+    public static final int DELAY = 2;
+    private LabelResourceId beginLabel = labelResourceId(5122);
+    private LabelResourceId endLabel = labelResourceId(9217);
 
     @Activate
     public void activate() {
@@ -123,6 +167,7 @@
         deviceProviderService = deviceProviderRegistry.register(this);
         linkProviderService = linkProviderRegistry.register(this);
         controller.addListener(listener);
+        mastershipService.addListener(masterListener);
         controller.addLinkListener(listener);
     }
 
@@ -135,6 +180,27 @@
         linkProviderService = null;
         controller.removeListener(listener);
         controller.removeLinkListener(listener);
+        mastershipService.removeListener(masterListener);
+    }
+
+    private class InternalMastershipListener implements MastershipListener {
+        @Override
+        public void event(MastershipEvent event) {
+            if (event.type() == MastershipEvent.Type.MASTER_CHANGED) {
+                if (mastershipService.getMasterFor(event.subject()) != null) {
+                    //Only for L3 device create label pool for that device
+                    Device device = deviceService.getDevice(event.subject());
+                    if (device == null) {
+                        log.debug("Device {} doesn't exist", event.subject());
+                        return;
+                    }
+                    //Reserve device label pool for L3 devices
+                    if (device.annotations().value(LSRID) != null) {
+                        createDevicePool(event.subject());
+                    }
+                }
+            }
+        }
     }
 
     /*
@@ -146,7 +212,7 @@
         public void addNode(BgpNodeLSNlriVer4 nodeNlri, PathAttrNlriDetails details) {
             log.debug("Add node {}", nodeNlri.toString());
 
-            if (deviceProviderService == null) {
+            if (deviceProviderService == null || deviceService == null) {
                 return;
             }
             Device.Type deviceType = ROUTER;
@@ -154,6 +220,13 @@
             DeviceId deviceId = deviceId(uri(nodeUri.toString()));
             ChassisId cId = new ChassisId();
 
+            /*
+             * Check if device is already there (available) , if yes not updating to core.
+             */
+            if (deviceService.isAvailable(deviceId)) {
+                return;
+            }
+
             DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
 
             newBuilder.set(AnnotationKeys.TYPE, "L3");
@@ -183,11 +256,13 @@
                     }
                 }
             }
+            DefaultAnnotations.Builder anntotations = DefaultAnnotations.builder();
+            anntotations = getAnnotations(newBuilder, true, details);
 
             DeviceDescription description = new DefaultDeviceDescription(uri(nodeUri.toString()), deviceType, UNKNOWN,
-                    UNKNOWN, UNKNOWN, UNKNOWN, cId, newBuilder.build());
-            deviceProviderService.deviceConnected(deviceId, description);
+                    UNKNOWN, UNKNOWN, UNKNOWN, cId, anntotations.build());
 
+            deviceProviderService.deviceConnected(deviceId, description);
         }
 
         @Override
@@ -200,6 +275,12 @@
 
             BgpDpid deviceUri = new BgpDpid(nodeNlri);
             DeviceId deviceId = deviceId(uri(deviceUri.toString()));
+
+            if (labelResourceAdminService != null) {
+                //Destroy local device label pool reserved for that device
+                labelResourceAdminService.destroyDevicePool(deviceId);
+            }
+
             deviceProviderService.deviceDisconnected(deviceId);
         }
 
@@ -211,6 +292,24 @@
                 return;
             }
             LinkDescription linkDes = buildLinkDes(linkNlri, details, true);
+
+            /*
+             * Update link ports and configure bandwidth on source and destination port using networkConfig service
+             * Only master of source link registers for bandwidth
+             */
+            if (mastershipService.isLocalMaster(linkDes.src().deviceId())) {
+                registerBandwidth(linkDes, details);
+            }
+
+            //Updating ports of the link
+            List<PortDescription> srcPortDescriptions = new LinkedList<>();
+            srcPortDescriptions.add(new DefaultPortDescription(linkDes.src().port(), true));
+            deviceProviderService.updatePorts(linkDes.src().deviceId(), srcPortDescriptions);
+
+            List<PortDescription> dstPortDescriptions = new LinkedList<>();
+            dstPortDescriptions.add(new DefaultPortDescription(linkDes.dst().port(), true));
+            deviceProviderService.updatePorts(linkDes.dst().deviceId(), dstPortDescriptions);
+
             linkProviderService.linkDetected(linkDes);
         }
 
@@ -273,7 +372,12 @@
 
             addOrDeletePseudoNode(isAddLink, localPseduo, remotePseduo, srcNodeNlri,
                      dstNodeNlri, srcId, dstId, details);
-            return new DefaultLinkDescription(src, dst, Link.Type.DIRECT, false);
+            DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
+            if (details != null) {
+                annotationBuilder = getAnnotations(annotationBuilder, false, details);
+            }
+
+            return new DefaultLinkDescription(src, dst, Link.Type.DIRECT, false, annotationBuilder.build());
         }
 
         private void addOrDeletePseudoNode(boolean isAddLink, boolean localPseduo, boolean remotePseduo,
@@ -322,10 +426,140 @@
             }
 
             LinkDescription linkDes = buildLinkDes(linkNlri, null, false);
+
+            /*
+             * Only master for the link src will release the bandwidth resource.
+             */
+            if (networkConfigService != null && mastershipService.isLocalMaster(linkDes.src().deviceId())) {
+                // Releases registered resource for this link
+                networkConfigService.removeConfig(linkDes.src(), BandwidthCapacity.class);
+                networkConfigService.removeConfig(linkDes.dst(), BandwidthCapacity.class);
+            }
+
             linkProviderService.linkVanished(linkDes);
         }
     }
 
+    // Creates label resource pool for the specific device. For all devices label range is 5122-9217
+    private void createDevicePool(DeviceId deviceId) {
+        if (labelResourceAdminService == null) {
+            return;
+        }
+
+        labelResourceAdminService.createDevicePool(deviceId, beginLabel, endLabel);
+    }
+
+    private void registerBandwidth(LinkDescription linkDes, PathAttrNlriDetails details) {
+        if (details ==  null) {
+            log.error("Couldnot able to register bandwidth ");
+            return;
+        }
+
+        List<BgpValueType> attribute = details.pathAttributes().stream()
+                .filter(attr -> attr instanceof LinkStateAttributes).collect(toList());
+        if (attribute.isEmpty()) {
+            return;
+        }
+
+        List<BgpValueType> tlvs = ((LinkStateAttributes) attribute.iterator().next()).linkStateAttributes();
+        float maxReservableBw = 0;
+
+        for (BgpValueType tlv : tlvs) {
+            switch (tlv.getType()) {
+            case LinkStateAttributes.ATTR_LINK_MAX_RES_BANDWIDTH:
+                maxReservableBw = ((BgpLinkAttrMaxLinkBandwidth) tlv).linkAttrMaxLinkBandwidth();
+                break;
+            default: // do nothing
+            }
+        }
+
+        if (maxReservableBw == 0.0) {
+            return;
+        }
+
+        //Configure bandwidth for src and dst port
+        BandwidthCapacity config = networkConfigService.addConfig(linkDes.src(), BandwidthCapacity.class);
+        config.capacity(Bandwidth.bps(maxReservableBw)).apply();
+
+        config = networkConfigService.addConfig(linkDes.dst(), BandwidthCapacity.class);
+        config.capacity(Bandwidth.bps(maxReservableBw)).apply();
+    }
+
+    private DefaultAnnotations.Builder getAnnotations(DefaultAnnotations.Builder annotationBuilder, boolean isNode,
+            PathAttrNlriDetails details) {
+
+        List<BgpValueType> attribute = details.pathAttributes().stream()
+                .filter(attr -> attr instanceof LinkStateAttributes).collect(toList());
+        if (attribute.isEmpty()) {
+            return annotationBuilder;
+        }
+        List<BgpValueType> tlvs = ((LinkStateAttributes) attribute.iterator().next()).linkStateAttributes();
+        boolean abrBit = false;
+        boolean externalBit = false;
+        boolean pseudo = false;
+        int igpMetric = 0;
+        int teMetric = 0;
+        byte[] areaId = null;
+        Ip4Address routerId = null;
+        for (BgpValueType tlv : tlvs) {
+            switch (tlv.getType()) {
+            case LinkStateAttributes.ATTR_NODE_FLAG_BITS:
+                abrBit = ((BgpAttrNodeFlagBitTlv) tlv).abrBit();
+                externalBit = ((BgpAttrNodeFlagBitTlv) tlv).externalBit();
+                break;
+            case NodeDescriptors.IGP_ROUTERID_TYPE:
+                if (tlv instanceof IsIsPseudonode || tlv instanceof OspfPseudonode) {
+                    pseudo = true;
+                }
+                break;
+            case LinkStateAttributes.ATTR_NODE_ISIS_AREA_ID:
+                areaId = ((BgpAttrNodeIsIsAreaId) tlv).attrNodeIsIsAreaId();
+                break;
+            case LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID:
+                routerId = ((BgpAttrRouterIdV4) tlv).attrRouterId();
+                break;
+            case LinkStateAttributes.ATTR_LINK_IGP_METRIC:
+                igpMetric = ((BgpLinkAttrIgpMetric) tlv).attrLinkIgpMetric();
+                break;
+            case LinkStateAttributes.ATTR_LINK_TE_DEFAULT_METRIC:
+                teMetric = ((BgpLinkAttrTeDefaultMetric) tlv).attrLinkDefTeMetric();
+                break;
+            default: // do nothing
+            }
+        }
+
+        // Annotations for device
+        if (isNode) {
+            boolean internalBit = false;
+            if (!abrBit && !externalBit) {
+                internalBit = true;
+            }
+
+            annotationBuilder.set(EXTERNAL_BIT, String.valueOf(externalBit));
+            annotationBuilder.set(ABR_BIT, String.valueOf(abrBit));
+            annotationBuilder.set(INTERNAL_BIT, String.valueOf(internalBit));
+            annotationBuilder.set(PSEUDO, String.valueOf(pseudo));
+
+            if (areaId != null) {
+                annotationBuilder.set(AREAID, new String(areaId));
+            }
+            if (routerId != null) {
+                // LsrID
+                annotationBuilder.set(LSRID, String.valueOf(routerId));
+            }
+        } else {
+            // Annotations for link
+            if (igpMetric != 0) {
+                annotationBuilder.set(COST, String.valueOf(igpMetric));
+            }
+
+            if (teMetric != 0) {
+                annotationBuilder.set(TE_COST, String.valueOf(teMetric));
+            }
+        }
+        return annotationBuilder;
+    }
+
     @Override
     public void triggerProbe(DeviceId deviceId) {
         // TODO Auto-generated method stub
diff --git a/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java b/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
index 7401fa5..4c3b097 100644
--- a/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
+++ b/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
@@ -16,6 +16,8 @@
 import static org.hamcrest.core.Is.is;
 import static org.hamcrest.core.IsNot.not;
 import static org.onosproject.net.Link.State.ACTIVE;
+import static org.onosproject.net.MastershipRole.MASTER;
+import static org.hamcrest.Matchers.nullValue;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -29,7 +31,11 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.junit.TestUtils.TestUtilsException;
 import org.onlab.packet.ChassisId;
+import org.onlab.packet.Ip4Address;
+import org.onlab.util.Bandwidth;
 import org.onosproject.bgp.controller.BgpLinkListener;
 import org.onosproject.bgp.controller.BgpNodeListener;
 import org.onosproject.bgpio.exceptions.BgpParseException;
@@ -43,9 +49,26 @@
 import org.onosproject.bgpio.types.AutonomousSystemTlv;
 import org.onosproject.bgpio.types.BgpValueType;
 import org.onosproject.bgpio.types.IsIsNonPseudonode;
+import org.onosproject.bgpio.types.LinkStateAttributes;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourcePool;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipListener;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.mastership.MastershipEvent.Type;
+import org.onosproject.net.link.LinkServiceAdapter;
 import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
 import org.onosproject.bgpio.types.RouteDistinguisher;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeIsIsAreaId;
+import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrIgpMetric;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrMaxLinkBandwidth;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
 import org.onosproject.bgpio.util.Constants;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.cluster.RoleInfo;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultDevice;
 import org.onosproject.net.DefaultLink;
@@ -53,6 +76,11 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
 import org.onosproject.net.MastershipRole;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
 import org.onosproject.net.device.DeviceDescription;
 import org.onosproject.net.device.DeviceProvider;
 import org.onosproject.net.device.DeviceProviderRegistry;
@@ -65,6 +93,15 @@
 import org.onosproject.net.link.LinkProviderRegistry;
 import org.onosproject.net.link.LinkProviderService;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.config.basics.BandwidthCapacity;
+import org.onosproject.net.resource.Resource;
+import org.onosproject.net.resource.ResourceAdminService;
+import org.onosproject.net.resource.ResourceId;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 
 /**
  * Test for BGP topology provider.
@@ -73,21 +110,31 @@
     private static final DeviceId DID2 = DeviceId.deviceId("l3:rd=0::routinguniverse=0:asn=10");
     private static final String UNKNOWN = new String("unknown");
     public static ProviderId providerId = new ProviderId("l3", "foo");
+    private static final NodeId NODE1 = new NodeId("Master1");
 
     private final BgpTopologyProvider provider = new BgpTopologyProvider();
     private final TestDeviceRegistry nodeRegistry = new TestDeviceRegistry();
     private final TestLinkRegistry linkRegistry = new TestLinkRegistry();
     private final MockBgpController controller = new MockBgpController();
     private MockDeviceService deviceService = new MockDeviceService();
+    private MockLinkService linkService = new MockLinkService();
+    private MockMastershipService mastershipService = new MockMastershipService();
+    private MockNetConfigRegistryAdapter networkConfigService = new MockNetConfigRegistryAdapter();
+    private MockLabelResourceService labelResourceAdminService = new MockLabelResourceService();
     private Map<DeviceId, Device> deviceMap = new HashMap<>();
-
+    private MastershipListener listener;
 
     @Before
-    public void startUp() {
+    public void startUp() throws TestUtilsException {
         provider.deviceProviderRegistry = nodeRegistry;
         provider.linkProviderRegistry = linkRegistry;
         provider.controller = controller;
         provider.deviceService = deviceService;
+        provider.linkService = linkService;
+        provider.labelResourceAdminService = labelResourceAdminService;
+        provider.mastershipService = mastershipService;
+        provider.networkConfigService = networkConfigService;
+        listener = TestUtils.getField(provider, "masterListener");
         provider.activate();
         assertThat("device provider should be registered", not(nodeRegistry.provider));
         assertThat("link provider should be registered", not(linkRegistry.linkProvider));
@@ -101,15 +148,177 @@
         provider.controller = null;
         provider.deviceService = null;
         provider.deviceProviderRegistry = null;
+        provider.linkService = null;
+        provider.mastershipService = null;
+        provider.networkConfigService = null;
+        provider.labelResourceAdminService = null;
         assertThat(controller.nodeListener, is(new HashSet<BgpNodeListener>()));
         assertThat(controller.linkListener, is(new HashSet<BgpLinkListener>()));
     }
 
+    private class MockLabelResourceService implements LabelResourceAdminService {
+
+        Map<DeviceId, LabelResourcePool> resourcePool = new HashMap<>();
+
+        @Override
+        public boolean createDevicePool(DeviceId deviceId, LabelResourceId beginLabel, LabelResourceId endLabel) {
+            LabelResourcePool labelResource = new LabelResourcePool(deviceId.toString(),
+                    beginLabel.labelId(),
+                    endLabel.labelId());
+            if (resourcePool.containsValue(labelResource)) {
+                return false;
+            }
+
+            resourcePool.put(deviceId, labelResource);
+            return true;
+        }
+
+        @Override
+        public boolean createGlobalPool(LabelResourceId beginLabel, LabelResourceId endLabel) {
+            // TODO Auto-generated method stub
+            return false;
+        }
+
+        @Override
+        public boolean destroyDevicePool(DeviceId deviceId) {
+            LabelResourcePool devicePool = resourcePool.get(deviceId);
+
+            if (devicePool == null) {
+                return false;
+            }
+
+            resourcePool.remove(deviceId);
+            return true;
+        }
+
+        @Override
+        public boolean destroyGlobalPool() {
+            // TODO Auto-generated method stub
+            return false;
+        }
+    }
+
+    /* Mock test for device service */
+    private class MockNetConfigRegistryAdapter extends NetworkConfigRegistryAdapter {
+        private ConfigFactory cfgFactory;
+        private Map<ConnectPoint, BandwidthCapacity> classConfig = new HashMap<>();
+
+        @Override
+        public void registerConfigFactory(ConfigFactory configFactory) {
+            cfgFactory = configFactory;
+        }
+
+        @Override
+        public void unregisterConfigFactory(ConfigFactory configFactory) {
+            cfgFactory = null;
+        }
+
+        @Override
+        public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) {
+            if (configClass == BandwidthCapacity.class) {
+                BandwidthCapacity devCap = new BandwidthCapacity();
+                classConfig.put((ConnectPoint) subject, devCap);
+
+                JsonNode node = new ObjectNode(new MockJsonNode());
+                ObjectMapper mapper = new ObjectMapper();
+                ConfigApplyDelegate delegate = new InternalApplyDelegate();
+                devCap.init((ConnectPoint) subject, null, node, mapper, delegate);
+                return (C) devCap;
+            }
+
+            return null;
+        }
+
+        @Override
+        public <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass) {
+            classConfig.remove(subject);
+        }
+
+        @Override
+        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+            if (configClass == BandwidthCapacity.class) {
+                return (C) classConfig.get(subject);
+            }
+            return null;
+        }
+
+        private class MockJsonNode extends JsonNodeFactory {
+        }
+
+        // Auxiliary delegate to receive notifications about changes applied to
+        // the network configuration - by the apps.
+        private class InternalApplyDelegate implements ConfigApplyDelegate {
+            @Override
+            public void onApply(Config config) {
+            }
+        }
+    }
+
+    private class MockMastershipService extends MastershipServiceAdapter {
+        @Override
+        public MastershipRole getLocalRole(DeviceId deviceId) {
+            return MASTER;
+        }
+
+        @Override
+        public boolean isLocalMaster(DeviceId deviceId) {
+            return getLocalRole(deviceId) == MASTER;
+        }
+
+        @Override
+        public NodeId getMasterFor(DeviceId deviceId) {
+            return NODE1;
+        }
+    }
+
+    private class MockResourceAdminService implements ResourceAdminService {
+        Map<ResourceId, List<Resource>> registeredRes = new HashMap<>();
+
+        @Override
+        public boolean register(List<Resource> resources) {
+            for (Resource res : resources) {
+                List<Resource> resource = new LinkedList<>();
+                resource.add(res);
+                if (registeredRes.containsKey(res.id())) {
+                    resource.addAll(registeredRes.get(res.id()));
+                }
+                registeredRes.put(res.id(), resource);
+            }
+            return true;
+        }
+
+        @Override
+        public boolean unregister(List<ResourceId> ids) {
+            for (ResourceId id : ids) {
+                if (registeredRes.containsKey(id)) {
+                    registeredRes.remove(id);
+                } else {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    private class MockLinkService extends LinkServiceAdapter {
+
+        @Override
+        public Link getLink(ConnectPoint src, ConnectPoint dst) {
+            for (Link link : linkRegistry.links) {
+                if (link.src().equals(src) && link.dst().equals(dst)) {
+                    return link;
+                }
+            }
+            return null;
+        }
+    }
+
     /* Class implement device test registry */
     private class TestDeviceRegistry implements DeviceProviderRegistry {
         DeviceProvider provider;
 
         Set<DeviceId> connected = new HashSet<>();
+        Map<DeviceId, List<PortDescription>> portUpdated = new HashMap<>();
 
         @Override
         public DeviceProviderService register(DeviceProvider provider) {
@@ -138,7 +347,7 @@
                 if (!deviceId.equals(DID2)) {
                     connected.add(deviceId);
                     Device device = new DefaultDevice(BgpTopologyProviderTest.providerId, deviceId, Device.Type.ROUTER,
-                            UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, new ChassisId());
+                            UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, new ChassisId(), deviceDescription.annotations());
                     deviceMap.put(deviceId, device);
                 }
             }
@@ -153,8 +362,7 @@
 
             @Override
             public void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
-                // TODO Auto-generated method stub
-
+                portUpdated.put(deviceId, portDescriptions);
             }
 
             @Override
@@ -202,9 +410,14 @@
 
             @Override
             public void linkDetected(LinkDescription linkDescription) {
-                links.add(DefaultLink.builder().src(linkDescription.src())
-                        .dst(linkDescription.dst()).state(ACTIVE).type(linkDescription.type())
-                        .providerId(BgpTopologyProviderTest.providerId).build());
+                links.add(DefaultLink.builder()
+                        .src(linkDescription.src())
+                        .dst(linkDescription.dst())
+                        .state(ACTIVE)
+                        .type(linkDescription.type())
+                        .providerId(BgpTopologyProviderTest.providerId)
+                        .annotations(linkDescription.annotations())
+                        .build());
             }
 
             @Override
@@ -349,6 +562,59 @@
         }
     }
 
+
+    /**
+     * Validate node is added to the device with all device annotations.
+     */
+    @Test
+    public void bgpTopologyProviderTestAddDevice4() {
+        LinkedList<BgpValueType> subTlvs = new LinkedList<>();
+        BgpValueType tlv = new AutonomousSystemTlv(100);
+        short deslength = AutonomousSystemTlv.LENGTH;
+        short desType = AutonomousSystemTlv.TYPE;
+
+        subTlvs.add(tlv);
+        BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(new NodeDescriptors(subTlvs, deslength,
+                                                                                               desType));
+        BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
+                                                           new RouteDistinguisher());
+
+        PathAttrNlriDetails details = new PathAttrNlriDetails();
+        details.setIdentifier(0);
+        details.setProtocolID(ProtocolType.DIRECT);
+        List<BgpValueType> pathAttributes = new LinkedList<>();
+        List<BgpValueType> linkStateAttr = new LinkedList<>();
+        tlv = BgpAttrNodeFlagBitTlv.of(true, true, true, false);
+        linkStateAttr.add(tlv);
+        tlv = BgpAttrNodeIsIsAreaId.of(new byte[] {01, 01, 01, 01});
+        linkStateAttr.add(tlv);
+        tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
+        linkStateAttr.add(tlv);
+        pathAttributes.add(new LinkStateAttributes(linkStateAttr));
+        details.setPathAttribute(pathAttributes);
+
+        for (BgpNodeListener l : controller.nodeListener) {
+            l.addNode(nodeNlri, details);
+
+            assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.ABR_BIT),
+                    is("false"));
+            assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.EXTERNAL_BIT),
+                    is("true"));
+            assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.INTERNAL_BIT),
+                    is("false"));
+            assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.PSEUDO),
+                    is("false"));
+            assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.AREAID).getBytes(),
+                    is(new byte[] {01, 01, 01, 01}));
+            assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.LSRID),
+                    is("1.1.1.1"));
+
+            assertThat(nodeRegistry.connected.size(), is(1));
+            l.deleteNode(nodeNlri);
+            assertThat(nodeRegistry.connected.size(), is(0));
+        }
+    }
+
     /**
      * Add a link and two devices.
      *
@@ -460,6 +726,82 @@
     }
 
     /**
+     * Add a link and delete a link with registering/unregistering bandwidth.
+     *
+     * @throws BgpParseException while adding or removing the link
+     * @throws InterruptedException while registering for bandwidth
+     */
+    @Test
+    public void bgpTopologyProviderTestAddLink3() throws BgpParseException, InterruptedException {
+        LinkedList<BgpValueType> localTlvs = new LinkedList<>();
+        LinkedList<BgpValueType> remoteTlvs = new LinkedList<>();
+        LinkedList<BgpValueType> linkdes = new LinkedList<>();
+        BgpValueType tlv = new AutonomousSystemTlv(10);
+        short deslength = AutonomousSystemTlv.LENGTH;
+        short desType = AutonomousSystemTlv.TYPE;
+
+        localTlvs.add(tlv);
+        remoteTlvs.add(tlv);
+        tlv = IsIsNonPseudonode.of(new byte[] {20, 20, 20, 20, 00, 20});
+        localTlvs.add(tlv);
+        tlv = IsIsNonPseudonode.of(new byte[] {30, 30, 30, 30, 00, 30});
+        remoteTlvs.add(tlv);
+        NodeDescriptors localNode = new NodeDescriptors(localTlvs, deslength, desType);
+        NodeDescriptors remoteNode = new NodeDescriptors(remoteTlvs, deslength, desType);
+        BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(localNode);
+        BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
+                                                           new RouteDistinguisher());
+
+        BgpNodeLSIdentifier remoteNodeDescriptors = new BgpNodeLSIdentifier(remoteNode);
+        BgpNodeLSNlriVer4 remNodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, remoteNodeDescriptors, false,
+                                                           new RouteDistinguisher());
+
+        PathAttrNlriDetails details = new PathAttrNlriDetails();
+        details.setIdentifier(0);
+        details.setProtocolID(ProtocolType.DIRECT);
+        List<BgpValueType> pathAttributes = new LinkedList<>();
+        details.setPathAttribute(pathAttributes);
+
+        tlv = LinkLocalRemoteIdentifiersTlv.of(99, 100);
+        linkdes.add(tlv);
+        BgpLinkLSIdentifier linkId = new BgpLinkLSIdentifier(localNode, remoteNode, linkdes);
+        BgpLinkLsNlriVer4 linkNlri = new BgpLinkLsNlriVer4((byte) Constants.DIRECT, 0, linkId,
+                new RouteDistinguisher(), false);
+
+        for (BgpNodeListener l : controller.nodeListener) {
+            l.addNode(nodeNlri, details);
+            assertThat(nodeRegistry.connected.size(), is(1));
+            l.addNode(remNodeNlri, details);
+            assertThat(nodeRegistry.connected.size(), is(2));
+            l.deleteNode(remNodeNlri);
+            assertThat(nodeRegistry.connected.size(), is(1));
+        }
+
+        List<BgpValueType> linkPathAttributes = new LinkedList<>();
+        List<BgpValueType> linkStateAttr = new LinkedList<>();
+        tlv = BgpLinkAttrIgpMetric.of(10, 4);
+        linkStateAttr.add(tlv);
+        tlv = BgpLinkAttrTeDefaultMetric.of(20);
+        linkStateAttr.add(tlv);
+        tlv = BgpLinkAttrMaxLinkBandwidth.of(30, LinkStateAttributes.ATTR_LINK_MAX_RES_BANDWIDTH);
+        linkStateAttr.add(tlv);
+        linkPathAttributes.add(new LinkStateAttributes(linkStateAttr));
+        details.setPathAttribute(linkPathAttributes);
+
+        for (BgpLinkListener l : controller.linkListener) {
+            l.addLink(linkNlri, details);
+            assertThat(linkRegistry.links.size(), is(1));
+            assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.COST),
+                    is("10"));
+            assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.TE_COST),
+                    is("20"));
+
+            l.deleteLink(linkNlri);
+            assertThat(linkRegistry.links.size(), is(0));
+        }
+    }
+
+    /**
      * Invalid link.
      *
      * @throws BgpParseException while adding or deleting a link
@@ -512,4 +854,188 @@
             assertThat(linkRegistry.links.size(), is(0));
         }
     }
+
+    /**
+     * Add device check label registration is done.
+     *
+     * @throws BgpParseException while adding a device
+     */
+    @Test
+    public void bgpTopologyProviderDeviceTestLabel1() throws BgpParseException {
+        LinkedList<BgpValueType> subTlvs = new LinkedList<>();
+        BgpValueType tlv = new AutonomousSystemTlv(100);
+        short deslength = AutonomousSystemTlv.LENGTH;
+        short desType = AutonomousSystemTlv.TYPE;
+
+        subTlvs.add(tlv);
+        BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(new NodeDescriptors(subTlvs, deslength,
+                                                                                               desType));
+        BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
+                                                           new RouteDistinguisher());
+
+        PathAttrNlriDetails details = new PathAttrNlriDetails();
+        details.setIdentifier(0);
+        details.setProtocolID(ProtocolType.DIRECT);
+        List<BgpValueType> pathAttributes = new LinkedList<>();
+        List<BgpValueType> linkStateAttributes = new LinkedList<>();
+        tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
+        linkStateAttributes.add(tlv);
+        pathAttributes.add(new LinkStateAttributes(linkStateAttributes));
+        details.setPathAttribute(pathAttributes);
+
+        for (BgpNodeListener l : controller.nodeListener) {
+            l.addNode(nodeNlri, details);
+            assertThat(nodeRegistry.connected.size(), is(1));
+        }
+
+        MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
+                new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
+
+        listener.event(event);
+        assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
+    }
+
+    /**
+     * Add device check label registration is done and delete node destroy label pool.
+     *
+     * @throws BgpParseException while adding a device
+     */
+    @Test
+    public void bgpTopologyProviderDeviceTestLabel2() throws BgpParseException {
+        LinkedList<BgpValueType> subTlvs = new LinkedList<>();
+        BgpValueType tlv = new AutonomousSystemTlv(100);
+        short deslength = AutonomousSystemTlv.LENGTH;
+        short desType = AutonomousSystemTlv.TYPE;
+
+        subTlvs.add(tlv);
+        BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(new NodeDescriptors(subTlvs, deslength,
+                                                                                               desType));
+        BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
+                                                           new RouteDistinguisher());
+
+        PathAttrNlriDetails details = new PathAttrNlriDetails();
+        details.setIdentifier(0);
+        details.setProtocolID(ProtocolType.DIRECT);
+        List<BgpValueType> pathAttributes = new LinkedList<>();
+        List<BgpValueType> linkStateAttributes = new LinkedList<>();
+        tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
+        linkStateAttributes.add(tlv);
+        pathAttributes.add(new LinkStateAttributes(linkStateAttributes));
+        details.setPathAttribute(pathAttributes);
+
+        for (BgpNodeListener l : controller.nodeListener) {
+            l.addNode(nodeNlri, details);
+            assertThat(nodeRegistry.connected.size(), is(1));
+            // Check label resource reserved for that device
+            MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
+                    new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
+            listener.event(event);
+            assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
+
+            l.deleteNode(nodeNlri);
+            assertThat(nodeRegistry.connected.size(), is(0));
+            assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(0));
+        }
+    }
+
+    /**
+     * Add a link register bandwidth and remove link unregister bandwidth.
+     *
+     * @throws BgpParseException while registering/unregistering bandwidth
+     */
+    @Test
+    public void bgpTopologyProviderDeviceTestLabel3() throws BgpParseException {
+        LinkedList<BgpValueType> localTlvs = new LinkedList<>();
+        LinkedList<BgpValueType> remoteTlvs = new LinkedList<>();
+        LinkedList<BgpValueType> linkdes = new LinkedList<>();
+        BgpValueType tlv = new AutonomousSystemTlv(10);
+        short deslength = AutonomousSystemTlv.LENGTH;
+        short desType = AutonomousSystemTlv.TYPE;
+
+        localTlvs.add(tlv);
+        remoteTlvs.add(tlv);
+        tlv = IsIsNonPseudonode.of(new byte[] {20, 20, 20, 20, 00, 20});
+        localTlvs.add(tlv);
+        tlv = IsIsNonPseudonode.of(new byte[] {30, 30, 30, 30, 00, 30});
+        remoteTlvs.add(tlv);
+        NodeDescriptors localNode = new NodeDescriptors(localTlvs, deslength, desType);
+        NodeDescriptors remoteNode = new NodeDescriptors(remoteTlvs, deslength, desType);
+        BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(localNode);
+        BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
+                                                           new RouteDistinguisher());
+
+        BgpNodeLSIdentifier remoteNodeDescriptors = new BgpNodeLSIdentifier(remoteNode);
+        BgpNodeLSNlriVer4 remNodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, remoteNodeDescriptors, false,
+                                                           new RouteDistinguisher());
+
+        PathAttrNlriDetails details = new PathAttrNlriDetails();
+        details.setIdentifier(0);
+        details.setProtocolID(ProtocolType.DIRECT);
+        List<BgpValueType> pathAttributes = new LinkedList<>();
+        List<BgpValueType> linkStateAttributes = new LinkedList<>();
+        tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
+        linkStateAttributes.add(tlv);
+        pathAttributes.add(new LinkStateAttributes(linkStateAttributes));
+        details.setPathAttribute(pathAttributes);
+
+        tlv = LinkLocalRemoteIdentifiersTlv.of(99, 100);
+        linkdes.add(tlv);
+        BgpLinkLSIdentifier linkId = new BgpLinkLSIdentifier(localNode, remoteNode, linkdes);
+        BgpLinkLsNlriVer4 linkNlri = new BgpLinkLsNlriVer4((byte) Constants.DIRECT, 0, linkId,
+                new RouteDistinguisher(), false);
+
+        for (BgpNodeListener l : controller.nodeListener) {
+            l.addNode(nodeNlri, details);
+            assertThat(nodeRegistry.connected.size(), is(1));
+            //Check label resource reserved for that device
+            MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
+                    new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
+            listener.event(event);
+            assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
+            l.addNode(remNodeNlri, details);
+            assertThat(nodeRegistry.connected.size(), is(2));
+            l.deleteNode(remNodeNlri);
+            assertThat(nodeRegistry.connected.size(), is(1));
+            assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
+        }
+
+        List<BgpValueType> linkPathAttributes = new LinkedList<>();
+        List<BgpValueType> linkStateAttr = new LinkedList<>();
+        tlv = BgpLinkAttrIgpMetric.of(10, 4);
+        linkStateAttr.add(tlv);
+        tlv = BgpLinkAttrTeDefaultMetric.of(20);
+        linkStateAttr.add(tlv);
+        tlv = BgpLinkAttrMaxLinkBandwidth.of(70, LinkStateAttributes.ATTR_LINK_MAX_RES_BANDWIDTH);
+        linkStateAttr.add(tlv);
+        linkPathAttributes.add(new LinkStateAttributes(linkStateAttr));
+        details.setPathAttribute(linkPathAttributes);
+
+        for (BgpLinkListener l : controller.linkListener) {
+            l.addLink(linkNlri, details);
+            assertThat(linkRegistry.links.size(), is(1));
+            assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.COST),
+                    is("10"));
+            assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.TE_COST),
+                    is("20"));
+
+            ConnectPoint src = new ConnectPoint(
+                    DeviceId.deviceId("l3:rd=0::routinguniverse=0:asn=10:isoid=1414.1414.0014"),
+                    PortNumber.portNumber(4294967395L));
+            ConnectPoint dst = new ConnectPoint(
+                    DeviceId.deviceId("l3:rd=0::routinguniverse=0:asn=10:isoid=1e1e.1e1e.001e"),
+                    PortNumber.portNumber(4294967396L));
+            BandwidthCapacity bandwidth = networkConfigService.getConfig(src, BandwidthCapacity.class);
+            assertThat(bandwidth.capacity().bps(), is(70.0 * 1_000_000L));
+
+            bandwidth = networkConfigService.getConfig(dst, BandwidthCapacity.class);
+            assertThat(bandwidth.capacity(), is(Bandwidth.bps(70.0 * 1_000_000L)));
+
+            l.deleteLink(linkNlri);
+            assertThat(linkRegistry.links.size(), is(0));
+            bandwidth = networkConfigService.getConfig(src, BandwidthCapacity.class);
+            assertThat(bandwidth, is(nullValue()));
+            bandwidth = networkConfigService.getConfig(dst, BandwidthCapacity.class);
+            assertThat(bandwidth, is(nullValue()));
+        }
+    }
 }
diff --git a/providers/pcep/packet/pom.xml b/providers/pcep/packet/pom.xml
new file mode 100644
index 0000000..9f3bd5e
--- /dev/null
+++ b/providers/pcep/packet/pom.xml
@@ -0,0 +1,33 @@
+<!--
+  ~ Copyright 2016-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-pcep-providers</artifactId>
+        <version>1.6.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>onos-pcep-provider-packet</artifactId>
+    <packaging>bundle</packaging>
+    <description>PCEP packet provider</description>
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-pcep-controller-api</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/PcepPacketProvider.java b/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/PcepPacketProvider.java
new file mode 100644
index 0000000..48f2408
--- /dev/null
+++ b/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/PcepPacketProvider.java
@@ -0,0 +1,140 @@
+package org.onosproject.provider.pcep.packet.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.TCP;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.DefaultPacketContext;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketProvider;
+import org.onosproject.net.packet.PacketProviderRegistry;
+import org.onosproject.net.packet.PacketProviderService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepClientController;
+import org.onosproject.pcep.controller.PcepPacketListener;
+import org.slf4j.Logger;
+
+/**
+ * Provider which uses an PCEP controller to process packets.
+ */
+@Component(immediate = true)
+@Service
+public class PcepPacketProvider extends AbstractProvider implements PacketProvider {
+
+    private static final Logger log = getLogger(PcepPacketProvider.class);
+    static final String PROVIDER_ID = "org.onosproject.provider.packet.pcep";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketProviderRegistry packetProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PcepClientController pcepClientController;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    PacketProviderService packetProviderService;
+
+    private InnerPacketProvider listener = new InnerPacketProvider();
+    public static final String LSRID = "lsrId";
+    public static final int PCEP_PORT = 4189;
+
+    /**
+     * Creates a Packet provider.
+     */
+    public PcepPacketProvider() {
+        super(new ProviderId("pcep", PROVIDER_ID));
+    }
+
+    @Activate
+    public void activate() {
+        packetProviderService = packetProviderRegistry.register(this);
+        pcepClientController.addPacketListener(listener);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        packetProviderRegistry.unregister(this);
+        pcepClientController.removePacketListener(listener);
+        log.info("Stopped");
+    }
+
+    private class InnerPacketProvider implements PcepPacketListener {
+        @Override
+        public void sendPacketIn(PccId pccId) {
+            TCP tcp = new TCP();
+            // Set the well known PCEP port. To be used to decide to process/discard the packet while processing.
+            tcp.setDestinationPort(PCEP_PORT);
+
+            IPv4 ipv4 = new IPv4();
+            ipv4.setProtocol(IPv4.PROTOCOL_TCP);
+            ipv4.setPayload(tcp);
+
+            Ethernet eth = new Ethernet();
+            eth.setEtherType(Ethernet.TYPE_IPV4);
+            eth.setPayload(ipv4);
+
+            // Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
+            String lsrId = String.valueOf(pccId.ipAddress());
+            DeviceId pccDeviceId = null;
+
+            // Find PCC deviceID from lsrId stored as annotations
+            Iterable<Device> devices = deviceService.getAvailableDevices();
+            for (Device dev : devices) {
+                if ("L3".equals(dev.annotations().value(AnnotationKeys.TYPE))
+                        && lsrId.equals(dev.annotations().value(LSRID))) {
+                    pccDeviceId = dev.id();
+                    break;
+                }
+            }
+
+            if (pccDeviceId == null) {
+                return;
+            }
+
+            InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(pccDeviceId,
+                                                                            PortNumber.portNumber(PCEP_PORT)),
+                                                           eth, null);
+
+            packetProviderService.processPacket(new PcepPacketContext(inPkt, null));
+        }
+    }
+
+    // Minimal PacketContext to make core and applications happy.
+    private final class PcepPacketContext extends DefaultPacketContext {
+        private PcepPacketContext(InboundPacket inPkt, OutboundPacket outPkt) {
+            super(System.currentTimeMillis(), inPkt, outPkt, false);
+        }
+
+        @Override
+        public void send() {
+            // We don't send anything out.
+            return;
+        }
+    }
+
+    @Override
+    public void emit(OutboundPacket packet) {
+        // Nothing to emit
+        return;
+
+    }
+}
diff --git a/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/package-info.java b/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/package-info.java
new file mode 100644
index 0000000..8e1ab9a
--- /dev/null
+++ b/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *Provider that uses PCEP controller as a means to send packets.
+ */
+package org.onosproject.provider.pcep.packet.impl;
\ No newline at end of file
diff --git a/providers/pcep/pom.xml b/providers/pcep/pom.xml
index 2569ca6..f193c67 100644
--- a/providers/pcep/pom.xml
+++ b/providers/pcep/pom.xml
@@ -27,5 +27,6 @@
         <module>topology</module>
         <module>tunnel</module>
         <module>app</module>
+        <module>packet</module>
   </modules>
 </project>
\ No newline at end of file
diff --git a/providers/pcep/topology/BUCK b/providers/pcep/topology/BUCK
index 56ba605..7a64a61 100644
--- a/providers/pcep/topology/BUCK
+++ b/providers/pcep/topology/BUCK
@@ -3,6 +3,9 @@
     '//protocols/ovsdb/api:onos-protocols-ovsdb-api',
     '//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc',
     '//apps/pcep-api:onos-apps-pcep-api',
+    '//protocols/pcep/api:onos-protocols-pcep-api',
+    '//protocols/pcep/pcepio:onos-protocols-pcep-pcepio',
+    '//core/api:onos-api-tests',
 ]
 
 osgi_jar_with_tests (
diff --git a/providers/pcep/topology/pom.xml b/providers/pcep/topology/pom.xml
index 6f017ce..adcebba 100644
--- a/providers/pcep/topology/pom.xml
+++ b/providers/pcep/topology/pom.xml
@@ -23,10 +23,20 @@
   <artifactId>onos-pcep-provider-topology</artifactId>
   <packaging>bundle</packaging>
   <description>PCEP topology provider</description>
-  	<dependencies>
-		<dependency>
-			<groupId>org.onosproject</groupId>
-			<artifactId>onos-app-pcep-api</artifactId>
-		</dependency>
-	</dependencies>
+     <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-pcep-api</artifactId>
+        </dependency>
+        <dependency>
+        <groupId>org.onosproject</groupId>
+            <artifactId>onos-pcep-controller-api</artifactId>
+        </dependency>
+        <dependency>
+             <groupId>org.onosproject</groupId>
+             <artifactId>onos-api</artifactId>
+             <classifier>tests</classifier>
+             <scope>test</scope>
+        </dependency>
+    </dependencies>
 </project>
\ No newline at end of file
diff --git a/providers/pcep/topology/src/main/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProvider.java b/providers/pcep/topology/src/main/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProvider.java
index 75a53f3..38239ed 100644
--- a/providers/pcep/topology/src/main/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProvider.java
+++ b/providers/pcep/topology/src/main/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProvider.java
@@ -62,6 +62,10 @@
 import org.onosproject.pcep.api.PcepOperator.OperationType;
 import org.onosproject.pcep.api.PcepSwitch;
 import org.onosproject.pcep.api.PcepSwitchListener;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepClient;
+import org.onosproject.pcep.controller.PcepClientController;
+import org.onosproject.pcep.controller.PcepNodeListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -115,18 +119,40 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ClusterService clusterService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PcepClientController pcepClientController;
+
     private DeviceProviderService deviceProviderService;
     private LinkProviderService linkProviderService;
 
     private HashMap<Long, List<PortDescription>> portMap = new HashMap<>();
     private InternalLinkProvider listener = new InternalLinkProvider();
 
+    /*
+     * For the client supporting SR capability.
+     */
+    public static final String SR_CAPABILITY = "srCapability";
+
+    /*
+     * For the client supporting PCECC capability.
+     */
+    public static final String PCECC_CAPABILITY = "pceccCapability";
+
+    /*
+     * For the client supporting label stack capability.
+     */
+    public static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
+
+    public static final String LSRID = "lsrId";
+    private static final String UNKNOWN = "unknown";
+
     @Activate
     public void activate() {
         linkProviderService = linkProviderRegistry.register(this);
         deviceProviderService = deviceProviderRegistry.register(this);
         controller.addListener(listener);
         controller.addLinkListener(listener);
+        pcepClientController.addNodeListener(listener);
     }
 
     @Deactivate
@@ -135,6 +161,7 @@
         linkProviderService = null;
         controller.removeListener(listener);
         controller.removeLinkListener(listener);
+        pcepClientController.removeNodeListener(listener);
     }
 
     private List<PortDescription> buildPortDescriptions(PcepDpid dpid,
@@ -225,7 +252,7 @@
     }
 
     private class InternalLinkProvider
-            implements PcepSwitchListener, PcepLinkListener {
+            implements PcepSwitchListener, PcepLinkListener, PcepNodeListener {
 
         @Override
         public void switchAdded(PcepDpid dpid) {
@@ -306,6 +333,51 @@
             }
         }
 
+        @Override
+        public void addNode(PcepClient pc) {
+            if (deviceProviderService == null) {
+                return;
+            }
+
+            //Right now device URI for PCEP devices is their LSRID
+            DeviceId deviceId = deviceId(uri(new PcepDpid(pc.getPccId().id().getIp4Address().toInt())));
+            ChassisId cId = new ChassisId();
+
+            Device.Type deviceType = Device.Type.ROUTER;
+
+            DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
+            //PCC capabilities (SR, PCECC and PCECC-SR)
+            annotationBuilder.set(SR_CAPABILITY, String.valueOf(pc.capability().srCapability()));
+            annotationBuilder.set(PCECC_CAPABILITY, String.valueOf(pc.capability().pceccCapability()));
+            annotationBuilder.set(LABEL_STACK_CAPABILITY, String.valueOf(pc.capability().labelStackCapability()));
+            //PccId is the lsrId contained in openMsg, if not present it will be the socket address
+            annotationBuilder.set(LSRID, String.valueOf(pc.getPccId().id()));
+
+            DeviceDescription description = new DefaultDeviceDescription(
+                    deviceId.uri(),
+                    deviceType,
+                    UNKNOWN,
+                    UNKNOWN,
+                    UNKNOWN,
+                    UNKNOWN,
+                    cId,
+                    annotationBuilder.build());
+
+            deviceProviderService.deviceConnected(deviceId, description);
+        }
+
+        @Override
+        public void deleteNode(PccId pccId) {
+            if (deviceProviderService == null || deviceService == null) {
+                return;
+            }
+            //TODO: In device manager, in deviceDisconnected() method, get the device but null check is not validated
+            if (deviceService.getDevice(DeviceId.deviceId(uri(new PcepDpid(pccId.id()
+                    .getIp4Address().toInt())))) == null) {
+                return;
+            }
+            deviceProviderService.deviceDisconnected(deviceId(uri(new PcepDpid(pccId.id().getIp4Address().toInt()))));
+        }
     }
 
     @Override
diff --git a/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientAdapter.java b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientAdapter.java
new file mode 100644
index 0000000..853bfd5
--- /dev/null
+++ b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientAdapter.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.pcep.topology.impl;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.jboss.netty.channel.Channel;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.LspKey;
+import org.onosproject.pcep.controller.PcepClient;
+import org.onosproject.pcep.controller.PcepSyncStatus;
+import org.onosproject.pcepio.protocol.PcepFactories;
+import org.onosproject.pcepio.protocol.PcepFactory;
+import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepStateReport;
+import org.onosproject.pcepio.protocol.PcepVersion;
+
+/**
+ * Representation of PCEP client adapter.
+ */
+public class PcepClientAdapter implements PcepClient {
+
+    private Channel channel;
+    protected String channelId;
+
+    private boolean connected;
+    private PccId pccId;
+    private ClientCapability capability;
+
+    private PcepVersion pcepVersion;
+    private PcepSyncStatus lspDbSyncStatus;
+    private PcepSyncStatus labelDbSyncStatus;
+    private Map<LspKey, Boolean> lspDelegationInfo = new HashMap<>();
+
+    /**
+     * Initialize instance with specified parameters.
+     *
+     * @param pccId PCC id
+     * @param pcepVersion PCEP message version
+     */
+    public void init(PccId pccId, PcepVersion pcepVersion) {
+        this.pccId = pccId;
+        this.pcepVersion = pcepVersion;
+    }
+
+    @Override
+    public final void disconnectClient() {
+        this.channel.close();
+    }
+
+    @Override
+    public final void sendMessage(PcepMessage m) {
+    }
+
+    @Override
+    public final void sendMessage(List<PcepMessage> msgs) {
+        try {
+            PcepMessage pcepMsg = msgs.get(0);
+            assertNotNull("PCEP MSG should be created.", pcepMsg);
+        } catch (RejectedExecutionException e) {
+            throw e;
+        }
+    }
+
+    @Override
+    public final boolean isConnected() {
+        return this.connected;
+    }
+
+    @Override
+    public String channelId() {
+        return channelId;
+    }
+
+    @Override
+    public final PccId getPccId() {
+        return this.pccId;
+    };
+
+    @Override
+    public final String getStringId() {
+        return this.pccId.toString();
+    }
+
+    @Override
+    public final void handleMessage(PcepMessage m) {
+    }
+
+    @Override
+    public boolean isOptical() {
+        return false;
+    }
+
+    @Override
+    public PcepFactory factory() {
+        return PcepFactories.getFactory(pcepVersion);
+    }
+
+    @Override
+    public void setLspDbSyncStatus(PcepSyncStatus syncStatus) {
+        this.lspDbSyncStatus = syncStatus;
+    }
+
+    @Override
+    public PcepSyncStatus lspDbSyncStatus() {
+        return lspDbSyncStatus;
+    }
+
+    @Override
+    public void setLabelDbSyncStatus(PcepSyncStatus syncStatus) {
+        this.labelDbSyncStatus = syncStatus;
+    }
+
+    @Override
+    public PcepSyncStatus labelDbSyncStatus() {
+        return labelDbSyncStatus;
+    }
+
+    @Override
+    public void setCapability(ClientCapability capability) {
+        this.capability = capability;
+    }
+
+    @Override
+    public ClientCapability capability() {
+        return capability;
+    }
+
+    @Override
+    public void addNode(PcepClient pc) {
+    }
+
+    @Override
+    public void deleteNode(PccId pccId) {
+    }
+
+    @Override
+    public void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag) {
+        lspDelegationInfo.put(lspKey, dFlag);
+    }
+
+    @Override
+    public Boolean delegationInfo(LspKey lspKey) {
+        return lspDelegationInfo.get(lspKey);
+    }
+
+    @Override
+    public void initializeSyncMsgList(PccId pccId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public List<PcepStateReport> getSyncMsgList(PccId pccId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void removeSyncMsgList(PccId pccId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void addSyncMsgToList(PccId pccId, PcepStateReport rptMsg) {
+        // TODO Auto-generated method stub
+
+    }
+}
diff --git a/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientControllerAdapter.java b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientControllerAdapter.java
new file mode 100644
index 0000000..74660b1
--- /dev/null
+++ b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientControllerAdapter.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.pcep.topology.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.onlab.packet.IpAddress;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepClient;
+import org.onosproject.pcep.controller.PcepClientController;
+import org.onosproject.pcep.controller.PcepClientListener;
+import org.onosproject.pcep.controller.PcepEventListener;
+import org.onosproject.pcep.controller.PcepNodeListener;
+import org.onosproject.pcep.controller.PcepPacketListener;
+import org.onosproject.pcep.controller.driver.PcepAgent;
+import org.onosproject.pcepio.protocol.PcepError;
+import org.onosproject.pcepio.protocol.PcepErrorInfo;
+import org.onosproject.pcepio.protocol.PcepErrorMsg;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepFactory;
+import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepVersion;
+
+import com.google.common.collect.Sets;
+
+import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_TYPE_19;
+import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_VALUE_5;
+
+/**
+ * Representation of PCEP client controller adapter.
+ */
+public class PcepClientControllerAdapter implements PcepClientController {
+
+    protected ConcurrentHashMap<PccId, PcepClient> connectedClients =
+            new ConcurrentHashMap<PccId, PcepClient>();
+
+    protected PcepClientAgent agent = new PcepClientAgent();
+    protected Set<PcepClientListener> pcepClientListener = new HashSet<>();
+
+    protected Set<PcepEventListener> pcepEventListener = Sets.newHashSet();
+    public Set<PcepNodeListener> pcepNodeListener = Sets.newHashSet();
+
+    @Activate
+    public void activate() {
+    }
+
+    @Deactivate
+    public void deactivate() {
+    }
+
+    @Override
+    public Collection<PcepClient> getClients() {
+        return connectedClients.values();
+    }
+
+    @Override
+    public PcepClient getClient(PccId pccId) {
+        if (null != connectedClients.get(pccId)) {
+            return connectedClients.get(pccId);
+        }
+        PcepClientAdapter pc = new PcepClientAdapter();
+        if (pccId.ipAddress().equals(IpAddress.valueOf(0xC010103))
+            || pccId.ipAddress().equals(IpAddress.valueOf(0xB6024E22))) {
+            pc.setCapability(new ClientCapability(true, false, false, false, false));
+        } else {
+            pc.setCapability(new ClientCapability(true, true, true, false, false));
+        }
+        pc.init(PccId.pccId(pccId.ipAddress()), PcepVersion.PCEP_1);
+        connectedClients.put(pccId, pc);
+        return pc;
+    }
+
+    @Override
+    public void addListener(PcepClientListener listener) {
+        if (!pcepClientListener.contains(listener)) {
+            this.pcepClientListener.add(listener);
+        }
+    }
+
+    @Override
+    public void addNodeListener(PcepNodeListener listener) {
+        pcepNodeListener.add(listener);
+    }
+
+    @Override
+    public void removeNodeListener(PcepNodeListener listener) {
+        pcepNodeListener.remove(listener);
+    }
+
+    @Override
+    public void removeListener(PcepClientListener listener) {
+        this.pcepClientListener.remove(listener);
+    }
+
+    @Override
+    public void addEventListener(PcepEventListener listener) {
+        pcepEventListener.add(listener);
+    }
+
+    @Override
+    public void removeEventListener(PcepEventListener listener) {
+        pcepEventListener.remove(listener);
+    }
+
+    @Override
+    public void writeMessage(PccId pccId, PcepMessage msg) {
+        this.getClient(pccId).sendMessage(msg);
+    }
+
+    @Override
+    public void processClientMessage(PccId pccId, PcepMessage msg) {
+
+        PcepClient pc = getClient(pccId);
+
+        switch (msg.getType()) {
+        case NONE:
+            break;
+        case OPEN:
+            break;
+        case KEEP_ALIVE:
+            //log.debug("Sending Keep Alive Message  to {" + pccIpAddress.toString() + "}");
+            pc.sendMessage(Collections.singletonList(pc.factory().buildKeepaliveMsg().build()));
+            break;
+        case PATH_COMPUTATION_REQUEST:
+            break;
+        case PATH_COMPUTATION_REPLY:
+            break;
+        case NOTIFICATION:
+            break;
+        case ERROR:
+            break;
+        case CLOSE:
+            //log.debug("Sending Close Message  to { }", pccIpAddress.toString());
+            pc.sendMessage(Collections.singletonList(pc.factory().buildCloseMsg().build()));
+            break;
+        case INITIATE:
+            if (!pc.capability().pcInstantiationCapability()) {
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+                        ERROR_TYPE_19, ERROR_VALUE_5)));
+            }
+            break;
+        case REPORT:
+            //Only update the listener if respective capability is supported else send PCEP-ERR msg
+            if (pc.capability().statefulPceCapability()) {
+                for (PcepEventListener l : pcepEventListener) {
+                    l.handleMessage(pccId, msg);
+                }
+            } else {
+                // Send PCEP-ERROR message.
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+                        ERROR_TYPE_19, ERROR_VALUE_5)));
+            }
+            break;
+        case UPDATE:
+            if (!pc.capability().statefulPceCapability()) {
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+                       ERROR_TYPE_19, ERROR_VALUE_5)));
+            }
+            break;
+        case LABEL_UPDATE:
+            if (!pc.capability().pceccCapability()) {
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+                        ERROR_TYPE_19, ERROR_VALUE_5)));
+            }
+            break;
+        case MAX:
+            break;
+        case END:
+            break;
+        default:
+            break;
+        }
+    }
+
+    @Override
+    public void closeConnectedClients() {
+        PcepClient pc;
+        for (PccId id : connectedClients.keySet()) {
+            pc = getClient(id);
+            pc.disconnectClient();
+        }
+    }
+
+    private PcepErrorMsg getErrMsg(PcepFactory factory, byte errorType, byte errorValue) {
+        LinkedList<PcepError> llPcepErr = new LinkedList<>();
+
+        LinkedList<PcepErrorObject> llerrObj = new LinkedList<>();
+        PcepErrorMsg errMsg;
+
+        PcepErrorObject errObj = factory.buildPcepErrorObject().setErrorValue(errorValue).setErrorType(errorType)
+                .build();
+
+        llerrObj.add(errObj);
+        PcepError pcepErr = factory.buildPcepError().setErrorObjList(llerrObj).build();
+
+        llPcepErr.add(pcepErr);
+
+        PcepErrorInfo errInfo = factory.buildPcepErrorInfo().setPcepErrorList(llPcepErr).build();
+
+        errMsg = factory.buildPcepErrorMsg().setPcepErrorInfo(errInfo).build();
+        return errMsg;
+    }
+
+    /**
+     * Implementation of an Pcep Agent which is responsible for
+     * keeping track of connected clients and the state in which
+     * they are.
+     */
+    public class PcepClientAgent implements PcepAgent {
+
+        @Override
+        public boolean addConnectedClient(PccId pccId, PcepClient pc) {
+
+            if (connectedClients.get(pccId) != null) {
+                return false;
+            } else {
+                connectedClients.put(pccId, pc);
+                for (PcepClientListener l : pcepClientListener) {
+                    l.clientConnected(pccId);
+                }
+                return true;
+            }
+        }
+
+        @Override
+        public boolean validActivation(PccId pccId) {
+            if (connectedClients.get(pccId) == null) {
+                //log.error("Trying to activate client but is not in "
+                //        + "connected switches: pccIp {}. Aborting ..", pccIpAddress.toString());
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public void removeConnectedClient(PccId pccId) {
+            connectedClients.remove(pccId);
+            for (PcepClientListener l : pcepClientListener) {
+                //log.warn("removal for {}", pccIpAddress.toString());
+                l.clientDisconnected(pccId);
+            }
+        }
+
+        @Override
+        public void processPcepMessage(PccId pccId, PcepMessage m) {
+            processClientMessage(pccId, m);
+        }
+
+        @Override
+        public void addNode(PcepClient pc) {
+            for (PcepNodeListener l : pcepNodeListener) {
+                l.addNode(pc);
+            }
+        }
+
+        @Override
+        public void deleteNode(PccId pccId) {
+            for (PcepNodeListener l : pcepNodeListener) {
+                l.deleteNode(pccId);
+            }
+        }
+
+        @Override
+        public boolean analyzeSyncMsgList(PccId pccId) {
+            // TODO Auto-generated method stub
+            return false;
+        }
+    }
+
+    @Override
+    public void addPacketListener(PcepPacketListener listener) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void removePacketListener(PcepPacketListener listener) {
+        // TODO Auto-generated method stub
+
+    }
+}
diff --git a/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepControllerAdapter.java b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepControllerAdapter.java
new file mode 100644
index 0000000..6b8bda9
--- /dev/null
+++ b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepControllerAdapter.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.provider.pcep.topology.impl;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.pcep.api.PcepController;
+import org.onosproject.pcep.api.PcepDpid;
+import org.onosproject.pcep.api.PcepLinkListener;
+import org.onosproject.pcep.api.PcepSwitch;
+import org.onosproject.pcep.api.PcepSwitchListener;
+import org.onosproject.pcep.api.PcepTunnel;
+import org.onosproject.pcep.api.PcepTunnelListener;
+
+/**
+ * Implementation of PCEP controller.
+ */
+public class PcepControllerAdapter implements PcepController {
+
+    @Override
+    public Iterable<PcepSwitch> getSwitches() {
+        return null;
+    }
+
+    @Override
+    public PcepSwitch getSwitch(PcepDpid did) {
+        return null;
+    }
+
+    @Override
+    public void addListener(PcepSwitchListener listener) {
+
+    }
+
+    @Override
+    public void removeListener(PcepSwitchListener listener) {
+    }
+
+    @Override
+    public void addLinkListener(PcepLinkListener listener) {
+    }
+
+    @Override
+    public void removeLinkListener(PcepLinkListener listener) {
+    }
+
+    @Override
+    public void addTunnelListener(PcepTunnelListener listener) {
+    }
+
+    @Override
+    public void removeTunnelListener(PcepTunnelListener listener) {
+    }
+
+    @Override
+    public PcepTunnel applyTunnel(DeviceId srcDid, DeviceId dstDid, long srcPort, long dstPort, long bandwidth,
+                                  String name) {
+        return null;
+    }
+
+    @Override
+    public Boolean deleteTunnel(String id) {
+        return null;
+    }
+
+    @Override
+    public Boolean updateTunnelBandwidth(String id, long bandwidth) {
+        return null;
+    }
+
+    @Override
+    public void getTunnelStatistics(String pcepTunnelId) {
+
+    }
+}
diff --git a/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProviderTest.java b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProviderTest.java
new file mode 100644
index 0000000..65a4c02
--- /dev/null
+++ b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProviderTest.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.onosproject.provider.pcep.topology.impl;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.net.Link.State.ACTIVE;
+import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.LABEL_STACK_CAPABILITY;
+import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.LSRID;
+import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.PCECC_CAPABILITY;
+import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.SR_CAPABILITY;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.ChassisId;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceProvider;
+import org.onosproject.net.device.DeviceProviderRegistry;
+import org.onosproject.net.device.DeviceProviderService;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.device.PortStatistics;
+import org.onosproject.net.link.LinkDescription;
+import org.onosproject.net.link.LinkProvider;
+import org.onosproject.net.link.LinkProviderRegistry;
+import org.onosproject.net.link.LinkProviderService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepClient;
+import org.onosproject.pcep.controller.PcepNodeListener;
+
+/**
+ * Test for PCEP topology provider.
+ */
+public class PcepTopologyProviderTest {
+    private static final String UNKNOWN = new String("unknown");
+    public static ProviderId providerId = new ProviderId("l3", "foo");
+    private final PcepClientControllerAdapter clientController = new PcepClientControllerAdapter();
+    private final PcepTopologyProvider provider = new PcepTopologyProvider();
+    private final MockDeviceRegistry nodeRegistry = new MockDeviceRegistry();
+    private final PcepControllerAdapter controller = new PcepControllerAdapter();
+    private final MockLinkRegistry linkRegistry = new MockLinkRegistry();
+    private final MockDeviceService deviceService = new MockDeviceService();
+    private Map<DeviceId, Device> deviceMap = new HashMap<>();
+
+    @Before
+    public void startUp() {
+        provider.pcepClientController = clientController;
+        provider.deviceProviderRegistry = nodeRegistry;
+        provider.linkProviderRegistry = linkRegistry;
+        provider.controller = controller;
+        provider.deviceService = deviceService;
+        provider.activate();
+    }
+
+    @After
+    public void tearDown() {
+        provider.deactivate();
+        provider.deviceProviderRegistry = null;
+        provider.pcepClientController = null;
+        provider.linkProviderRegistry = null;
+        provider.controller = null;
+        provider.deviceService = null;
+    }
+
+    /* Class implement device test registry */
+    private class MockLinkRegistry implements LinkProviderRegistry {
+        LinkProvider linkProvider;
+        Set<Link> links = new HashSet<>();
+
+        @Override
+        public LinkProviderService register(LinkProvider provider) {
+            this.linkProvider = provider;
+            return new MockProviderService();
+        }
+
+        @Override
+        public void unregister(LinkProvider provider) {
+            // TODO Auto-generated method stub
+        }
+
+        @Override
+        public Set<ProviderId> getProviders() {
+            return null;
+        }
+
+        private class MockProviderService implements LinkProviderService {
+
+            @Override
+            public void linkDetected(LinkDescription linkDescription) {
+                links.add(DefaultLink.builder().src(linkDescription.src())
+                        .dst(linkDescription.dst()).state(ACTIVE).type(linkDescription.type())
+                        .providerId(ProviderId.NONE).build());
+            }
+
+            @Override
+            public void linkVanished(LinkDescription linkDescription) {
+                links.remove(DefaultLink.builder().src(linkDescription.src())
+                        .dst(linkDescription.dst()).state(ACTIVE).type(linkDescription.type())
+                        .providerId(ProviderId.NONE).build());
+            }
+
+            @Override
+            public void linksVanished(ConnectPoint connectPoint) {
+                // TODO Auto-generated method stub
+            }
+
+            @Override
+            public void linksVanished(DeviceId deviceId) {
+                // TODO Auto-generated method stub
+            }
+
+            @Override
+            public LinkProvider provider() {
+                // TODO Auto-generated method stub
+                return null;
+            }
+        }
+    }
+
+    /* Class implement device test registry */
+    private class MockDeviceRegistry implements DeviceProviderRegistry {
+        DeviceProvider provider;
+
+        Set<DeviceId> connected = new HashSet<>();
+
+        @Override
+        public DeviceProviderService register(DeviceProvider provider) {
+            this.provider = provider;
+            return new MockProviderService();
+        }
+
+        @Override
+        public void unregister(DeviceProvider provider) {
+        }
+
+        @Override
+        public Set<ProviderId> getProviders() {
+            return null;
+        }
+
+        private class MockProviderService implements DeviceProviderService {
+
+            @Override
+            public DeviceProvider provider() {
+                return null;
+            }
+
+            @Override
+            public void deviceConnected(DeviceId deviceId, DeviceDescription deviceDescription) {
+                connected.add(deviceId);
+                Device device = new DefaultDevice(ProviderId.NONE, deviceId, Device.Type.ROUTER, UNKNOWN, UNKNOWN,
+                        UNKNOWN, UNKNOWN, new ChassisId(), deviceDescription.annotations());
+                deviceMap.put(deviceId, device);
+            }
+
+            @Override
+            public void deviceDisconnected(DeviceId deviceId) {
+                connected.remove(deviceId);
+                deviceMap.remove(deviceId);
+            }
+
+            @Override
+            public void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
+                // TODO Auto-generated method stub
+            }
+
+            @Override
+            public void portStatusChanged(DeviceId deviceId, PortDescription portDescription) {
+                // TODO Auto-generated method stub
+            }
+
+            @Override
+            public void receivedRoleReply(DeviceId deviceId, MastershipRole requested, MastershipRole response) {
+                // TODO Auto-generated method stub
+            }
+
+            @Override
+            public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) {
+                // TODO Auto-generated method stub
+            }
+        }
+    }
+
+    /* Mock test for device service */
+    private class MockDeviceService extends DeviceServiceAdapter {
+        @Override
+        public Device getDevice(DeviceId deviceId) {
+            return deviceMap.get(deviceId);
+        }
+    }
+
+    /**
+     * Adds the PCEP device and removes it.
+     */
+    @Test
+    public void testPcepTopologyProviderTestAddDevice1() {
+        PcepClient pc = clientController.getClient(PccId.pccId(IpAddress.valueOf("1.1.1.1")));
+        for (PcepNodeListener l : clientController.pcepNodeListener) {
+            pc.setCapability(new ClientCapability(true, true, false, true, true));
+            l.addNode(pc);
+            assertThat(nodeRegistry.connected.size(), is(1));
+            assertThat(deviceMap.keySet().iterator().next(), is(DeviceId.deviceId("l3:1.1.1.1")));
+            assertThat(deviceMap.values().iterator().next().annotations().value(LABEL_STACK_CAPABILITY), is("true"));
+            assertThat(deviceMap.values().iterator().next().annotations().value(LSRID), is("1.1.1.1"));
+            assertThat(deviceMap.values().iterator().next().annotations().value(PCECC_CAPABILITY), is("true"));
+            assertThat(deviceMap.values().iterator().next().annotations().value(SR_CAPABILITY), is("true"));
+
+            l.deleteNode(pc.getPccId());
+            assertThat(nodeRegistry.connected.size(), is(0));
+        }
+    }
+}
diff --git a/providers/pcep/tunnel/BUCK b/providers/pcep/tunnel/BUCK
index ce09ba2..465f5fd 100644
--- a/providers/pcep/tunnel/BUCK
+++ b/providers/pcep/tunnel/BUCK
@@ -6,6 +6,7 @@
     '//incubator/api:onos-incubator-api',
     '//protocols/pcep/pcepio:onos-protocols-pcep-pcepio',
     '//protocols/pcep/api:onos-protocols-pcep-api',
+    '//protocols/pcep/ctl:onos-protocols-pcep-ctl',
 ]
 
 TEST_DEPS = [
diff --git a/providers/pcep/tunnel/pom.xml b/providers/pcep/tunnel/pom.xml
index 2a72154..5241bb8 100644
--- a/providers/pcep/tunnel/pom.xml
+++ b/providers/pcep/tunnel/pom.xml
@@ -49,5 +49,10 @@
             <version>${project.version} </version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-pcep-controller-impl</artifactId>
+            <version>${project.version} </version>
+        </dependency>
     </dependencies>
 </project>
diff --git a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepLspStatus.java b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepLspStatus.java
deleted file mode 100644
index ef628ed..0000000
--- a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepLspStatus.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.provider.pcep.tunnel.impl;
-
-import org.onosproject.incubator.net.tunnel.Tunnel.State;
-
-/**
- * Representation of the PCEP LSP state.
- */
-public enum PcepLspStatus {
-
-    /**
-     * Signifies that the LSP is not active.
-     */
-    DOWN,
-
-    /**
-     * Signifies that the LSP is signalled.
-     */
-    UP,
-
-    /**
-     * Signifies that the LSP is up and carrying traffic.
-     */
-    ACTIVE,
-
-    /**
-     * Signifies that the LSP is being torn down, resources are being released.
-     */
-    GOING_DOWN,
-
-    /**
-     * Signifies that the LSP is being signalled.
-     */
-    GOING_UP;
-
-    /**
-     * Returns the applicable PCEP LSP status corresponding to ONOS tunnel state.
-     *
-     * @param tunnelState ONOS tunnel state
-     */
-    public static PcepLspStatus getLspStatusFromTunnelStatus(State tunnelState) {
-
-        switch (tunnelState) {
-
-        case INIT:
-            return PcepLspStatus.DOWN;
-
-        case ESTABLISHED:
-            return PcepLspStatus.GOING_UP;
-
-        case ACTIVE:
-            return PcepLspStatus.UP;
-
-        case FAILED: // fall through
-        case INACTIVE: // LSP is administratively down.
-        default:
-            return PcepLspStatus.DOWN;
-        }
-    }
-
-    /**
-     * Returns the applicable ONOS tunnel state corresponding to PCEP LSP status.
-     *
-     * @param lspState PCEP LSP status
-     */
-    public static State getTunnelStatusFromLspStatus(PcepLspStatus lspState) {
-
-        switch (lspState) {
-
-        case DOWN:
-            return State.FAILED;
-
-        case UP: // fall through
-        case ACTIVE:
-            return State.ACTIVE;
-
-        case GOING_DOWN:
-            return State.FAILED;
-
-        case GOING_UP:
-            return State.ESTABLISHED;
-
-        default:
-            return State.FAILED;
-        }
-    }
-}
diff --git a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
index cb1922a..c77187a 100644
--- a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
+++ b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
@@ -36,6 +36,7 @@
 import org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint;
 import org.onosproject.incubator.net.tunnel.Tunnel;
 import org.onosproject.incubator.net.tunnel.Tunnel.State;
+import org.onosproject.incubator.net.tunnel.TunnelAdminService;
 import org.onosproject.incubator.net.tunnel.TunnelDescription;
 import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
 import org.onosproject.incubator.net.tunnel.TunnelId;
@@ -45,11 +46,14 @@
 import org.onosproject.incubator.net.tunnel.TunnelProviderService;
 import org.onosproject.incubator.net.tunnel.TunnelService;
 import org.onosproject.incubator.net.tunnel.TunnelStatistics;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.AnnotationKeys;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultAnnotations;
 import org.onosproject.net.DefaultAnnotations.Builder;
 import org.onosproject.net.DefaultLink;
 import org.onosproject.net.DefaultPath;
+import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.ElementId;
 import org.onosproject.net.IpElementId;
@@ -57,6 +61,7 @@
 import org.onosproject.net.Path;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.provider.AbstractProvider;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.pcep.api.PcepController;
@@ -68,12 +73,14 @@
 import org.onosproject.pcep.api.PcepTunnel.PathType;
 import org.onosproject.pcep.api.PcepTunnelListener;
 import org.onosproject.pcep.api.PcepTunnelStatistics;
+import org.onosproject.pcep.controller.LspKey;
 import org.onosproject.pcep.controller.PccId;
 import org.onosproject.pcep.controller.PcepClient;
 import org.onosproject.pcep.controller.PcepClientController;
 import org.onosproject.pcep.controller.PcepClientListener;
 import org.onosproject.pcep.controller.PcepEventListener;
-import org.onosproject.pcep.controller.PcepSyncStatus;
+import org.onosproject.pcep.controller.PcepLspSyncAction;
+import org.onosproject.pcep.controller.impl.PcepLspStatus;
 import org.onosproject.pcepio.exceptions.PcepParseException;
 import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
 import org.onosproject.pcepio.protocol.PcepAttribute;
@@ -83,6 +90,7 @@
 import org.onosproject.pcepio.protocol.PcepInitiateMsg;
 import org.onosproject.pcepio.protocol.PcepLspObject;
 import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepMetricObject;
 import org.onosproject.pcepio.protocol.PcepMsgPath;
 import org.onosproject.pcepio.protocol.PcepReportMsg;
 import org.onosproject.pcepio.protocol.PcepSrpObject;
@@ -107,8 +115,10 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.Map;
 import java.util.Optional;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Strings.isNullOrEmpty;
@@ -125,14 +135,18 @@
 import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LSP_SIG_TYPE;
 import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCC_TUNNEL_ID;
 import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PLSP_ID;
-import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCE_INIT;
+import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.DELEGATE;
+import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.COST_TYPE;
 import static org.onosproject.provider.pcep.tunnel.impl.RequestType.CREATE;
 import static org.onosproject.provider.pcep.tunnel.impl.RequestType.DELETE;
 import static org.onosproject.provider.pcep.tunnel.impl.RequestType.LSP_STATE_RPT;
 import static org.onosproject.provider.pcep.tunnel.impl.RequestType.UPDATE;
-import static org.onosproject.pcep.controller.PcepSyncStatus.IN_SYNC;
-import static org.onosproject.pcep.controller.PcepSyncStatus.SYNCED;
 import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
+import static org.onosproject.pcep.controller.PcepLspSyncAction.REMOVE;
+import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_UPDATE;
+import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_DELETE;
+import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.IGP_METRIC;
+import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.TE_METRIC;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -148,6 +162,11 @@
     private static final long MIN_BANDWIDTH = 64;
     private static final String BANDWIDTH_UINT = "kbps";
     static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
+    public static final long IDENTIFIER_SET = 0x100000000L;
+    public static final long SET = 0xFFFFFFFFL;
+    private static final int DELAY = 2;
+    private static final int WAIT_TIME = 5;
+    public static final String LSRID = "lsrId";
 
     static final int POLL_INTERVAL = 10;
     @Property(name = "tunnelStatsPollFrequency", intValue = POLL_INTERVAL,
@@ -171,6 +190,15 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ComponentConfigService cfgService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TunnelAdminService tunnelAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
     TunnelProviderService service;
 
     HashMap<String, TunnelId> tunnelMap = new HashMap<String, TunnelId>();
@@ -182,10 +210,6 @@
     protected PcepTunnelApiMapper pcepTunnelApiMapper = new PcepTunnelApiMapper();
     private static final int DEFAULT_BANDWIDTH_VALUE = 10;
 
-    private Map<IpAddress, Map<TunnelId, Tunnel>> preSyncLspDbMap = new HashMap<>();
-    private Map<IpAddress, List<Tunnel>> syncCompleteDeleteList = new HashMap<>();
-    private Map<IpAddress, List<Tunnel>> syncCompleteUpdateList = new HashMap<>();
-
     /**
      * Creates a Tunnel provider.
      */
@@ -263,7 +287,8 @@
         }
 
         //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
-        if (pc.capability().pcInstantiationCapability()) {
+        //Only master will initiate setup tunnel
+        if (pc.capability().pcInstantiationCapability() && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
             pcepSetupTunnel(tunnel, path, pc);
         }
     }
@@ -300,7 +325,10 @@
             return;
         }
 
-        if (pc.capability().pcInstantiationCapability()) {
+        //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
+        //Only master will initiate setup tunnel
+        if (pc.capability().pcInstantiationCapability()
+                && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
             pcepSetupTunnel(tunnel, path, pc);
         }
     }
@@ -327,7 +355,9 @@
             return;
         }
 
-        if (pc.capability().pcInstantiationCapability()) {
+        //Only master will release tunnel
+        if (pc.capability().pcInstantiationCapability()
+                && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
             pcepReleaseTunnel(tunnel, pc);
         }
     }
@@ -358,7 +388,9 @@
             return;
         }
 
-        if (pc.capability().pcInstantiationCapability()) {
+        //Only master will release tunnel
+        if (pc.capability().pcInstantiationCapability()
+                && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
             pcepReleaseTunnel(tunnel, pc);
         }
     }
@@ -384,7 +416,12 @@
             return;
         }
 
-        if (pc.capability().statefulPceCapability()) {
+        // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
+        // LSP].If annotation is null D flag is not set else it is set.
+        if (pc.capability().statefulPceCapability()
+                && pc.delegationInfo(
+                        new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
+                                .annotations().value(LOCAL_LSP_ID)))) != null) {
             pcepUpdateTunnel(tunnel, path, pc);
         }
     }
@@ -416,7 +453,12 @@
             return;
         }
 
-        if (pc.capability().statefulPceCapability()) {
+        // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
+        // LSP].If annotation is null D flag is not set else it is set.
+        if (pc.capability().statefulPceCapability()
+                && pc.delegationInfo(
+                        new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
+                                .annotations().value(LOCAL_LSP_ID)))) != null) {
             pcepUpdateTunnel(tunnel, path, pc);
         }
     }
@@ -480,6 +522,43 @@
         return tunnelId;
     }
 
+    private void tunnelUpdated(Tunnel tunnel, Path path) {
+        handleTunnelUpdate(tunnel, path);
+    }
+
+    //Handles tunnel updated using tunnel admin service[specially to update annotations].
+    private void handleTunnelUpdate(Tunnel tunnel, Path path) {
+
+        if (tunnel.type() == MPLS) {
+            pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.tunnelId());
+
+            tunnelAdminService.updateTunnel(tunnel, path);
+
+            return;
+        }
+
+        Tunnel tunnelOld = tunnelQueryById(tunnel.tunnelId());
+        if (tunnelOld.type() != Tunnel.Type.VLAN) {
+            error("Illegal tunnel type. Only support VLAN tunnel update.");
+            return;
+        }
+
+        long bandwidth = Long
+                .parseLong(tunnel.annotations().value("bandwidth"));
+        if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
+            error("Update failed, invalid bandwidth.");
+            return;
+        }
+        String pcepTunnelId = getPcepTunnelKey(tunnel.tunnelId());
+
+        checkNotNull(pcepTunnelId, "Invalid tunnel id");
+        if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
+            error("Update failed,maybe invalid bandwidth.");
+            return;
+        }
+        tunnelAdminService.updateTunnel(tunnel, path);
+    }
+
     @Override
     public void tunnelRemoved(TunnelDescription tunnel) {
         if (tunnel.type() == MPLS) {
@@ -681,7 +760,6 @@
                                                                 path,
                                                                 annotations);
         return tunnel;
-
     }
 
     /**
@@ -1098,41 +1176,8 @@
                         log.debug("SRP ID in handle message " + srpId);
 
                         if (!(pcepTunnelApiMapper.checkFromTunnelRequestQueue(srpId))) {
-
-                            // Check the sync status
-                            if (lspObj.getSFlag()) {
-                                if (pcepClientController.getClient(pccId).lspDbSyncStatus() != IN_SYNC) {
-                                    pcepClientController.getClient(pccId).setLspDbSyncStatus(IN_SYNC);
-
-                                    // On starting LSP-DB sync, store LSP DB locally for this PCC.
-                                    Map<TunnelId, Tunnel> preSyncLspDb = new HashMap<>();
-                                    Collection<Tunnel> queriedTunnels = tunnelService.queryTunnel(MPLS);
-
-                                    for (Tunnel tunnel : queriedTunnels) {
-                                        if (((IpTunnelEndPoint) tunnel.src()).ip().equals(pccId.ipAddress())) {
-                                            preSyncLspDb.put(tunnel.tunnelId(), tunnel);
-                                        }
-                                    }
-
-                                    preSyncLspDbMap.put(pccId.ipAddress(), preSyncLspDb);
-                                    syncCompleteDeleteList.put(pccId.ipAddress(), new LinkedList<>());
-                                    syncCompleteUpdateList.put(pccId.ipAddress(), new LinkedList<>());
-                                }
-                                handleRptWithoutSrpId(stateRpt, pccId, IN_SYNC);
-                                continue;
-
-                            } else if (pcepClientController.getClient(pccId).lspDbSyncStatus() == IN_SYNC) {
-                                // If sync flag is not set in the msg, and the
-                                // previous state was "in sync" means this is
-                                // end of sync message. PCRpt for end of sync
-                                // does not carry any LSP report.
-                                pcepClientController.getClient(pccId).setLspDbSyncStatus(SYNCED);
-                                handleEndOfSyncAction(pccId);
-                                continue;
-                            }
-
-                            // For PCRpt without matching SRP id not during LSPDB sync.
-                            handleRptWithoutSrpId(stateRpt, pccId, SYNCED);
+                            // For PCRpt without matching SRP id.
+                            handleRptWithoutSrpId(stateRpt, pccId);
                             continue;
                         }
 
@@ -1226,27 +1271,30 @@
             }
         }
 
-        private void handleRptWithoutSrpId(PcepStateReport stateRpt, PccId pccId, PcepSyncStatus syncStatus) {
-            ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
-            PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
-            checkNotNull(msgPath);
-            PcepEroObject eroObj = msgPath.getEroObject();
-            if (eroObj == null) {
-                log.error("ERO object is null in report message.");
-                return;
-            }
-            Path path = buildPathFromEroObj(eroObj, providerId);
+        private SparseAnnotations getAnnotations(PcepLspObject lspObj, StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv,
+                float bandwidth, LspType lspType, String costType) {
 
-            int bandwidth = 0;
-            if (msgPath.getBandwidthObject() != null) {
-                bandwidth = msgPath.getBandwidthObject().getBandwidth();
-            }
+            Builder builder = DefaultAnnotations.builder();
 
             /*
-             * To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
-             * from PCE.
+             * [RFC 5440] The absence of the METRIC object MUST be interpreted by the PCE as a path computation request
+             * for which no constraints need be applied to any of the metrics.
              */
-            PcepSrpObject srpObj = stateRpt.getSrpObject();
+            if (costType != null) {
+                builder.set(COST_TYPE, costType);
+            }
+
+            SparseAnnotations annotations = builder
+                    .set(BANDWIDTH, (new Float(bandwidth)).toString()).set(LSP_SIG_TYPE, lspType.name())
+                    .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
+                    .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
+                    .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId()))
+                    .set(DELEGATE, String.valueOf(lspObj.getDFlag()))
+                    .build();
+            return annotations;
+        }
+
+        private LspType getLspType(PcepSrpObject srpObj) {
             LspType lspType = WITH_SIGNALLING;
 
             if (null != srpObj) {
@@ -1266,6 +1314,55 @@
                     }
                 }
             }
+            return lspType;
+        }
+
+        private void handleRptWithoutSrpId(PcepStateReport stateRpt, PccId pccId) {
+            ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
+            String costType = null;
+            PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
+            checkNotNull(msgPath);
+            PcepEroObject eroObj = msgPath.getEroObject();
+            if (eroObj == null) {
+                log.error("ERO object is null in report message.");
+                return;
+            }
+
+            PcepAttribute attributes = msgPath.getPcepAttribute();
+            int cost = 0;
+            if (attributes != null && attributes.getMetricObjectList() != null) {
+                ListIterator<PcepMetricObject> iterator = attributes.getMetricObjectList().listIterator();
+                PcepMetricObject metricObj = iterator.next();
+
+                while (metricObj != null) {
+                    if (metricObj.getBType() == IGP_METRIC) {
+                        costType = "COST";
+                    } else if (metricObj.getBType() == TE_METRIC) {
+                        costType = "TE_COST";
+                    }
+
+                    if (costType != null) {
+                        cost = metricObj.getMetricVal();
+                        log.debug("Path cost {}", cost);
+                        break;
+                    }
+                    metricObj = iterator.next();
+                }
+            }
+
+            Path path = buildPathFromEroObj(eroObj, providerId, cost);
+
+            float bandwidth = 0;
+            if (msgPath.getBandwidthObject() != null) {
+                bandwidth = msgPath.getBandwidthObject().getBandwidth();
+            }
+
+            /*
+             * To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
+             * from PCE.
+             */
+            PcepSrpObject srpObj = stateRpt.getSrpObject();
+            LspType lspType = getLspType(srpObj);
 
             PcepLspObject lspObj = stateRpt.getLspObject();
             ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
@@ -1287,7 +1384,6 @@
                     break;
                 }
             }
-
             /*
              * Draft says: The LSP-IDENTIFIERS TLV MUST be included in the LSP object in PCRpt messages for
              * RSVP-signaled LSPs. For ONOS PCECC implementation, it is mandatory.
@@ -1303,6 +1399,14 @@
                     .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
             Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
 
+            // Store delegation flag info and that LSP info because only delegated PCE sends update message
+            // Storing if D flag is set, if not dont store. while checking whether delegation if annotation for D flag
+            // not present then non-delegated , if present it is delegated.
+            if (lspObj.getDFlag()) {
+                pcepClientController.getClient(pccId).setLspAndDelegationInfo(
+                        new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId()), lspObj.getDFlag());
+            }
+
             Tunnel tunnel = null;
             // Asynchronous status change message from PCC for LSP reported earlier.
             for (Tunnel tunnelObj : tunnelQueryResult) {
@@ -1321,7 +1425,6 @@
                     }
                     continue;
                 }
-
                 if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId()) && (Integer
                         .valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
                     tunnel = tunnelObj;
@@ -1330,6 +1433,7 @@
             }
 
             DefaultTunnelDescription td;
+            SparseAnnotations annotations = null;
             State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
             if (tunnel == null) {
                 if (lspObj.getRFlag()) {
@@ -1340,91 +1444,96 @@
                     return;
                 }
 
-                if (lspObj.getCFlag()) {
-                    /*
-                     * While in sync, if PCRpt is received for PCE init LSP and PCE doesn't have entry, mark to send
-                     * delete message on end of sync.
-                     */
-                    SparseAnnotations annotations = DefaultAnnotations.builder()
-                            .set(BANDWIDTH, (new Integer(bandwidth)).toString())
-                            .set(LSP_SIG_TYPE, lspType.name())
-                            .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
-                            .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
-                            .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId())).build();
+                DeviceId deviceId = getDevice(pccId);
+                if (deviceId == null) {
+                    log.error("Ingress deviceId not found");
+                    return;
+                }
+                annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
 
-                    // Gnenerate tunnel id for the temporary tunnel.
-                    String onosTunnelId = "PCC" + String.valueOf(ipv4LspIdenTlv.getTunnelId());
-                    Tunnel tunnelToBeDeleted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
-                                                                 new DefaultGroupId(0), TunnelId.valueOf(onosTunnelId),
-                                                                 TunnelName.tunnelName(String
-                                                                         .valueOf(pathNameTlv.getValue())),
-                                                                 path, annotations);
+                td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
+                        0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
+                        annotations);
 
-                    /*
-                     * Need to send PCInitiate delete msg for a tunnel which does not exist at PCE. For that some dummy
-                     * data-structures need to be populated.
-                     */
-                    PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelToBeDeleted, path, RequestType.DELETE);
-                    pcepTunnelData.setPlspId(lspObj.getPlspId());
-                    pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
-                    pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
-                    pcepTunnelApiMapper.handleCreateTunnelRequestQueue(0, pcepTunnelData);
-
-                    /*
-                     * Add to the list of tunnels for which PCInit delete will be sent at the end of sync.
-                     */
-                    List<Tunnel> tunnelToBeDeletedList = syncCompleteDeleteList.get(pccId.ipAddress());
-                    tunnelToBeDeletedList.add(tunnelToBeDeleted);
-                    syncCompleteDeleteList.put(pccId.ipAddress(), tunnelToBeDeletedList);
+                // Do not support PCC initiated LSP after LSP DB sync is completed.
+                if (!lspObj.getSFlag() && !lspObj.getCFlag()) {
+                    log.error("Received PCC initiated LSP while not in sync.");
                     return;
                 }
 
-                SparseAnnotations annotations = DefaultAnnotations.builder()
-                        .set(BANDWIDTH, (new Integer(bandwidth)).toString())
-                        .set(LSP_SIG_TYPE, lspType.name())
-                        .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
-                        .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
-                        .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId())).build();
+                /*
+                 * If ONOS instance is master for PCC then set delegated flag as annotation and add the tunnel to store.
+                 * Because all LSPs need not be delegated, hence mastership for the PCC is confirmed whereas not the
+                 * delegation set to all LSPs.If ONOS is not the master for that PCC then check if D flag is set, if yes
+                 * wait for 2 seconds [while master has added the tunnel to the store] then update the tunnel. Tunnel is
+                 * updated because in case of resilency only delegated LSPs are recomputed and only delegated PCE can
+                 * send update message to that client.
+                 *
+                 * 1)Master can 1st get the Rpt message
+                 * a)Master adds the tunnel into core.
+                 * b)If a non-master for ingress gets Rpt message with D flag set[as delegation owner]
+                 *  after master, then runs timer then update the tunnel with D flag set.
+                 * 2)Non-Master can 1st get the Rpt message
+                 * a)Non-Master runs the timer check for the tunnel then updates the tunnel with D flag set
+                 * b)Master would have got the message while the non-master running timer, hence master adds
+                 *  tunnel to core
+                 *
+                 * In general always master adds the tunnel to the core
+                 * while delegated owner [master or non-master with D flag set] always updates the tunnel running timer
+                 */
+                if (mastershipService.isLocalMaster(deviceId)) {
+                    TunnelId tId = tunnelAdded(td, tunnelState);
+                    Tunnel tunnelInserted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
+                            tunnelState, new DefaultGroupId(0), tId, TunnelName.tunnelName(String.valueOf(pathNameTlv
+                                    .getValue())), path, annotations);
 
-                td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
-                                                  new DefaultGroupId(0), providerId,
-                                                  TunnelName.tunnelName(String.valueOf(pathNameTlv.getValue())), path,
-                                                  annotations);
-
-                TunnelId tId = tunnelAdded(td, tunnelState);
-                Tunnel tunnelInserted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
-                                                          tunnelState, new DefaultGroupId(0), tId,
-                                                          TunnelName.tunnelName(String.valueOf(pathNameTlv.getValue())),
-                                                          path, annotations);
-
-                PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelInserted, path, LSP_STATE_RPT);
-                pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
-                pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
+                    PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelInserted, path, LSP_STATE_RPT);
+                    pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
+                    pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
+                } else if (!mastershipService.isLocalMaster(deviceId) && lspObj.getDFlag()) {
+                    //Start timer then update the tunnel with D flag
+                    tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
+                }
                 return;
             }
 
-            if ((syncStatus == IN_SYNC) && (lspObj.getCFlag()) && (tunnelState != tunnel.state())) {
-                // Mark to send PCUpd msg with state known at PCE.
-                List<Tunnel> tunnelToBeUpdateList = syncCompleteUpdateList.get(pccId.ipAddress());
-                tunnelToBeUpdateList.add(tunnel);
-                syncCompleteUpdateList.put(pccId.ipAddress(), tunnelToBeUpdateList);
-                return;
+            //delegated owner will update can be a master or non-master
+            if (lspObj.getDFlag()) {
+                annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
+                td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
+                        0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
+                        annotations);
+                tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
             }
+            removeOrUpdatetunnel(tunnel, pccId, lspObj, providerId, tunnelState);
+            return;
+        }
 
-            td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
-                                                                       tunnel.type(), tunnel.groupId(), providerId,
-                                                                       tunnel.tunnelName(), tunnel.path(),
-                                                                       (SparseAnnotations) tunnel.annotations());
-
+        private void removeOrUpdatetunnel(Tunnel tunnel, PccId pccId, PcepLspObject lspObj, ProviderId providerId,
+                State tunnelState) {
+            DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
+                    tunnel.type(), tunnel.groupId(), providerId, tunnel.tunnelName(), tunnel.path(),
+                    (SparseAnnotations) tunnel.annotations());
             if (lspObj.getRFlag()) {
                 tunnelRemoved(td);
             } else {
-                if (syncStatus == IN_SYNC) {
-                    markLspDbEntryAsLatest(pccId, tunnel.tunnelId());
-                }
                 tunnelUpdated(td, tunnelState);
             }
-            return;
+        }
+
+        private void tunnelUpdateInDelegatedCase(PccId pccId, SparseAnnotations annotations,
+                DefaultTunnelDescription td, ProviderId providerId) {
+            //Wait for 2sec then query tunnel based on ingress PLSP-ID and local LSP-ID
+
+            /*
+             * If ONOS is not the master for that PCC then check if D flag is set, if yes wait [while
+             * master has added the tunnel to the store] then update the tunnel.
+             */
+            ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+
+            // Thread is started after 2 seconds first time later periodically after 2 seconds to update the tunnel
+            executor.scheduleAtFixedRate(new UpdateDelegation(td, providerId, annotations, pccId,
+                    executor), DELAY, DELAY, TimeUnit.SECONDS);
         }
 
         /**
@@ -1432,9 +1541,10 @@
          *
          * @param eroObj ERO object
          * @param providerId provider id
+         * @param cost cost of path
          * @return path object
          */
-        private Path buildPathFromEroObj(PcepEroObject eroObj, ProviderId providerId) {
+        private Path buildPathFromEroObj(PcepEroObject eroObj, ProviderId providerId, int cost) {
             checkNotNull(eroObj);
             List<Link> links = new ArrayList<Link>();
             LinkedList<PcepValueType> llSubObj = eroObj.getSubObjects();
@@ -1474,7 +1584,8 @@
                     // the other sub objects are not required
                 }
             }
-            return new DefaultPath(providerId, links, 0, EMPTY);
+
+            return new DefaultPath(providerId, links, cost, EMPTY);
         }
 
         @Override
@@ -1493,44 +1604,14 @@
             TunnelStatistics tunnelStatistics = buildTunnelStatistics(pcepTunnelStatistics);
             tunnelStatisticsMap.put(id, tunnelStatistics);
         }
-    }
 
-    @Override
-    public Tunnel tunnelQueryById(TunnelId tunnelId) {
-        return service.tunnelQueryById(tunnelId);
-    }
+        @Override
+        public void handleEndOfSyncAction(Tunnel tunnel, PcepLspSyncAction endOfSyncAction) {
 
-    /**
-     * Removes the entry from temporary copy of LSPDB, signifying its status as upto date.
-     *
-     * @param pccId the key for temporary LSPDB
-     * @param tunnelId the tunnel id for which information is updated.
-     */
-    private void markLspDbEntryAsLatest(PccId pccId, TunnelId tunnelId) {
-        checkNotNull(pccId);
-        checkNotNull(tunnelId);
-
-        Map<TunnelId, Tunnel> preSyncLspDb = preSyncLspDbMap.get(pccId.ipAddress());
-        checkNotNull(preSyncLspDb);
-
-        preSyncLspDb.remove(tunnelId);
-        preSyncLspDbMap.put(pccId.ipAddress(), preSyncLspDb);
-    }
-
-    /**
-     * Sends PCInit, PCInit(R) or PCUpd messages for initiated LSPs at the end
-     * of LSP DB sync based on actions decided while sync was in progress. Also
-     * triggers label DB sync.
-     *
-     * @param pccId the key for temporary DBs storing required end of sync
-     *            actions.
-     */
-    private void handleEndOfSyncAction(PccId pccId) {
-
-        Map<TunnelId, Tunnel> preSyncLspDb = preSyncLspDbMap.get(pccId.ipAddress());
-        checkNotNull(preSyncLspDb);
-
-        for (Tunnel tunnel : preSyncLspDb.values()) {
+            if (endOfSyncAction == SEND_UPDATE) {
+                updateTunnel(tunnel, tunnel.path());
+                return;
+            }
 
             TunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(),
                                                                 tunnel.src(), tunnel.dst(),
@@ -1541,41 +1622,133 @@
                                                                 tunnel.path(),
                                                                 (SparseAnnotations) tunnel.annotations());
 
-            if ((tunnel.annotations().value(PCE_INIT) == null)
-                    || (tunnel.annotations().value(PCE_INIT).equals("false"))) {
 
-                tunnelRemoved(td);
-            } else {
+            if (endOfSyncAction == PcepLspSyncAction.UNSTABLE) {
+
                 // Send PCInit msg again after global reoptimization.
                 tunnelUpdated(td, UNSTABLE);
 
                 // To remove the old tunnel from store whose PLSPID is not
                 // recognized by ingress PCC.
                 tunnelRemoved(td);
+
+            } else if (endOfSyncAction == REMOVE) {
+                tunnelRemoved(td);
             }
         }
 
-        List<Tunnel> tunnelsToBeDeletedList = syncCompleteDeleteList.get(pccId.ipAddress());
-        checkNotNull(tunnelsToBeDeletedList);
-        for (Tunnel tunnel: tunnelsToBeDeletedList) {
-            releaseTunnel(tunnel);
+        @Override
+        public void handleEndOfSyncAction(PccId pccId, PcepMessage msg, PcepLspSyncAction endOfSyncAction) {
+            try {
+                if ((msg instanceof PcepInitiateMsg) && (endOfSyncAction == SEND_DELETE)) {
+                    PcepClient pc = pcepClientController.getClient(pccId);
+                    LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = ((PcepInitiateMsg) msg)
+                            .getPcInitiatedLspRequestList();
+                    PcInitiatedLspRequest pcInitMsg = llPcInitiatedLspRequestList.iterator().next();
+
+                    if (pcInitMsg != null) {
+                        PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(SrpIdGenerators.create())
+                                .setRFlag(true).build();
+
+                        PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest()
+                                .setLspObject(pcInitMsg.getLspObject()).setSrpObject(srpobj).build();
+
+                        llPcInitiatedLspRequestList.remove(pcInitMsg);
+                        llPcInitiatedLspRequestList.add(releaseLspRequest);
+
+                        PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
+                                .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
+
+                        pc.sendMessage(Collections.singletonList(pcInitiateMsg));
+                    }
+                }
+            } catch (PcepParseException e) {
+                log.error("Exception occured while sending initiate delete message {}", e.getMessage());
+            }
+        }
+    }
+    @Override
+    public Tunnel tunnelQueryById(TunnelId tunnelId) {
+        return service.tunnelQueryById(tunnelId);
+    }
+
+
+    private DeviceId getDevice(PccId pccId) {
+        // Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
+        IpAddress lsrId = pccId.ipAddress();
+        String lsrIdentifier = String.valueOf(lsrId);
+
+        // Find PCC deviceID from lsrId stored as annotations
+        Iterable<Device> devices = deviceService.getAvailableDevices();
+        for (Device dev : devices) {
+            if (dev.annotations().value(AnnotationKeys.TYPE).equals("L3")
+                    && dev.annotations().value(LSRID).equals(lsrIdentifier)) {
+                return dev.id();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Updates the tunnel with updated tunnel annotation after a delay of two seconds and checks it till
+     * tunnel is found.
+     */
+    private class UpdateDelegation implements Runnable {
+        DefaultTunnelDescription td;
+        ProviderId providerId;
+        SparseAnnotations annotations;
+        PccId pccId;
+        ScheduledExecutorService executor;
+
+        /**
+         * Creates an instance of UpdateDelegation.
+         *
+         * @param td tunnel description
+         * @param providerId provider id
+         * @param annotations tunnel annotations
+         * @param pccId PCEP client id
+         * @param executor service of delegated owner
+         */
+        public UpdateDelegation(DefaultTunnelDescription td, ProviderId providerId, SparseAnnotations annotations,
+                PccId pccId, ScheduledExecutorService executor) {
+            this.td = td;
+            this.providerId = providerId;
+            this.annotations = annotations;
+            this.pccId = pccId;
+            this.executor = executor;
         }
 
-        List<Tunnel> tunnelsToBeUpdatedList = syncCompleteUpdateList.get(pccId.ipAddress());
-        checkNotNull(tunnelsToBeUpdatedList);
-        for (Tunnel tunnel: tunnelsToBeUpdatedList) {
-            updateTunnel(tunnel, tunnel.path());
-        }
+        //Temporary using annotations later will use projection/network config service
+        @Override
+        public void run() {
+            Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(td.src(), td.dst());
+            TunnelId tempTunnelId = null;
+            for (Tunnel t : tunnelQueryResult) {
+                if (t.annotations().value(LOCAL_LSP_ID) == null ||  t.annotations().value(PLSP_ID) == null) {
+                    continue;
+                }
 
-        /* On end of sync, empty all temporary data structures. */
-        preSyncLspDbMap.remove(pccId.ipAddress());
-        syncCompleteDeleteList.remove(pccId.ipAddress());
-        syncCompleteUpdateList.remove(pccId.ipAddress());
+                if (t.annotations().value(LOCAL_LSP_ID).equals(td.annotations().value(LOCAL_LSP_ID))
+                        && t.annotations().value(PLSP_ID).equals(td.annotations().value(PLSP_ID))
+                        && ((IpTunnelEndPoint) t.src()).ip().equals(pccId.id())) {
+                    tempTunnelId = t.tunnelId();
+                    break;
+                }
+            }
 
-        // TODO: If SR capable, send a notification to
-        // PCE APP to start label DB sync.
-        if (true) {
-            pcepClientController.getClient(pccId).setLabelDbSyncStatus(IN_SYNC);
+            //If tunnel is found update the tunnel and shutdown the thread otherwise thread will be executing
+            //periodically
+            if (tempTunnelId != null) {
+                Tunnel tunnel = new DefaultTunnel(providerId, td.src(), td.dst(), MPLS, new DefaultGroupId(0),
+                        tempTunnelId, td.tunnelName(), td.path(), annotations);
+                tunnelUpdated(tunnel, td.path());
+                executor.shutdown();
+                try {
+                    executor.awaitTermination(WAIT_TIME, TimeUnit.SECONDS);
+                } catch (InterruptedException e) {
+                    log.error("updating delegation failed");
+                }
+            }
         }
     }
 }
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java
index daf315a..aafdfaa 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java
@@ -17,17 +17,22 @@
 
 import static org.junit.Assert.assertNotNull;
 
+import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.RejectedExecutionException;
 
 import org.jboss.netty.channel.Channel;
 import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.LspKey;
 import org.onosproject.pcep.controller.PccId;
 import org.onosproject.pcep.controller.PcepClient;
 import org.onosproject.pcep.controller.PcepSyncStatus;
 import org.onosproject.pcepio.protocol.PcepFactories;
 import org.onosproject.pcepio.protocol.PcepFactory;
 import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepStateReport;
 import org.onosproject.pcepio.protocol.PcepVersion;
 
 /**
@@ -45,6 +50,8 @@
     private PcepVersion pcepVersion;
     private PcepSyncStatus lspDbSyncStatus;
     private PcepSyncStatus labelDbSyncStatus;
+    private Map<LspKey, Boolean> lspDelegationInfo = new HashMap<>();
+    private Map<PccId, List<PcepStateReport>> sycRptCache = new HashMap<>();
 
     /**
      * Initialize instance with specified parameters.
@@ -139,4 +146,45 @@
     public ClientCapability capability() {
         return capability;
     }
+
+    @Override
+    public void addNode(PcepClient pc) {
+    }
+
+    @Override
+    public void deleteNode(PccId pccId) {
+    }
+
+    @Override
+    public void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag) {
+        lspDelegationInfo.put(lspKey, dFlag);
+    }
+
+    @Override
+    public Boolean delegationInfo(LspKey lspKey) {
+        return lspDelegationInfo.get(lspKey);
+    }
+
+    @Override
+    public void initializeSyncMsgList(PccId pccId) {
+        List<PcepStateReport> rptMsgList = new LinkedList<>();
+        sycRptCache.put(pccId, rptMsgList);
+    }
+
+    @Override
+    public List<PcepStateReport> getSyncMsgList(PccId pccId) {
+        return sycRptCache.get(pccId);
+    }
+
+    @Override
+    public void removeSyncMsgList(PccId pccId) {
+        sycRptCache.remove(pccId);
+    }
+
+    @Override
+    public void addSyncMsgToList(PccId pccId, PcepStateReport rptMsg) {
+        List<PcepStateReport> rptMsgList = sycRptCache.get(pccId);
+        rptMsgList.add(rptMsg);
+        sycRptCache.put(pccId, rptMsgList);
+    }
 }
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
index 822d8b6..dd82aac 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
@@ -24,13 +24,13 @@
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Deactivate;
-import org.onlab.packet.IpAddress;
-import org.onosproject.pcep.controller.ClientCapability;
 import org.onosproject.pcep.controller.PccId;
 import org.onosproject.pcep.controller.PcepClient;
 import org.onosproject.pcep.controller.PcepClientController;
 import org.onosproject.pcep.controller.PcepClientListener;
 import org.onosproject.pcep.controller.PcepEventListener;
+import org.onosproject.pcep.controller.PcepNodeListener;
+import org.onosproject.pcep.controller.PcepPacketListener;
 import org.onosproject.pcep.controller.driver.PcepAgent;
 import org.onosproject.pcepio.protocol.PcepError;
 import org.onosproject.pcepio.protocol.PcepErrorInfo;
@@ -57,6 +57,8 @@
     protected Set<PcepClientListener> pcepClientListener = new HashSet<>();
 
     protected Set<PcepEventListener> pcepEventListener = Sets.newHashSet();
+    public Set<PcepNodeListener> pcepNodeListener = Sets.newHashSet();
+    protected Set<PcepPacketListener> pcepPacketListener = Sets.newHashSet();
 
     @Activate
     public void activate() {
@@ -73,16 +75,11 @@
 
     @Override
     public PcepClient getClient(PccId pccId) {
-        if (null != connectedClients.get(pccId)) {
+        if (connectedClients.get(pccId) != null) {
             return connectedClients.get(pccId);
         }
         PcepClientAdapter pc = new PcepClientAdapter();
-        if (pccId.ipAddress().equals(IpAddress.valueOf(0xC010103))
-            || pccId.ipAddress().equals(IpAddress.valueOf(0xB6024E22))) {
-            pc.setCapability(new ClientCapability(true, false, false));
-        } else {
-            pc.setCapability(new ClientCapability(true, true, true));
-        }
+
         pc.init(PccId.pccId(pccId.ipAddress()), PcepVersion.PCEP_1);
         connectedClients.put(pccId, pc);
         return pc;
@@ -96,6 +93,16 @@
     }
 
     @Override
+    public void addNodeListener(PcepNodeListener listener) {
+        pcepNodeListener.add(listener);
+    }
+
+    @Override
+    public void removeNodeListener(PcepNodeListener listener) {
+        pcepNodeListener.remove(listener);
+    }
+
+    @Override
     public void removeListener(PcepClientListener listener) {
         this.pcepClientListener.remove(listener);
     }
@@ -111,6 +118,16 @@
     }
 
     @Override
+    public void addPacketListener(PcepPacketListener listener) {
+        pcepPacketListener.add(listener);
+    }
+
+    @Override
+    public void removePacketListener(PcepPacketListener listener) {
+        pcepPacketListener.remove(listener);
+    }
+
+    @Override
     public void writeMessage(PccId pccId, PcepMessage msg) {
         this.getClient(pccId).sendMessage(msg);
     }
@@ -254,5 +271,25 @@
         public void processPcepMessage(PccId pccId, PcepMessage m) {
             processClientMessage(pccId, m);
         }
+
+        @Override
+        public void addNode(PcepClient pc) {
+            for (PcepNodeListener l : pcepNodeListener) {
+                l.addNode(pc);
+            }
+        }
+
+        @Override
+        public void deleteNode(PccId pccId) {
+            for (PcepNodeListener l : pcepNodeListener) {
+                l.deleteNode(pccId);
+            }
+        }
+
+        @Override
+        public boolean analyzeSyncMsgList(PccId pccId) {
+            // TODO Auto-generated method stub
+            return false;
+        }
     }
 }
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java
index ec9c1aa..22a683b 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java
@@ -40,6 +40,7 @@
 import org.onosproject.incubator.net.tunnel.Tunnel;
 import org.onosproject.incubator.net.tunnel.TunnelId;
 import org.onosproject.incubator.net.tunnel.TunnelName;
+import org.onosproject.mastership.MastershipServiceAdapter;
 import org.onosproject.net.Annotations;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultAnnotations;
@@ -49,7 +50,10 @@
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceServiceAdapter;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
 import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
 
 /**
@@ -64,12 +68,16 @@
     private final PcepControllerAdapter ctl = new PcepControllerAdapter();
     private final PcepTunnelApiMapper pcepTunnelAPIMapper = new PcepTunnelApiMapper();
     private final TunnelServiceAdapter  tunnelService = new TunnelServiceAdapter();
+    private final DeviceServiceAdapter  deviceService = new DeviceServiceAdapter();
+    private final MastershipServiceAdapter  mastershipService = new MastershipServiceAdapter();
 
     @Before
     public void setUp() throws IOException {
         tunnelProvider.tunnelProviderRegistry = registry;
         tunnelProvider.pcepClientController = controller;
         tunnelProvider.controller = ctl;
+        tunnelProvider.deviceService = deviceService;
+        tunnelProvider.mastershipService = mastershipService;
         tunnelProvider.tunnelService = tunnelService;
         tunnelProvider.pcepTunnelApiMapper = pcepTunnelAPIMapper;
         tunnelProvider.cfgService = new ComponentConfigAdapter();
@@ -125,6 +133,8 @@
         tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
 
         tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+        controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E20))).setCapability(
+                new ClientCapability(true, true, true, true, true));
 
         tunnelProvider.releaseTunnel(tunnel);
         assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -179,6 +189,8 @@
         tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
 
         tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+        controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E22))).setCapability(
+                new ClientCapability(true, false, false, true, true));
 
         tunnelProvider.releaseTunnel(tunnel);
         assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
@@ -233,6 +245,8 @@
         tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
 
         tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+        controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E20))).setCapability(
+                new ClientCapability(true, true, true, true, true));
 
         tunnelProvider.releaseTunnel(tunnel);
         assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -287,6 +301,8 @@
         tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
 
         tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+        controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E20))).setCapability(
+                new ClientCapability(true, true, true, true, true));
 
         tunnelProvider.releaseTunnel(tunnel);
         assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -298,5 +314,7 @@
         tunnelProvider.controller = null;
         tunnelProvider.pcepClientController = null;
         tunnelProvider.tunnelProviderRegistry = null;
+        tunnelProvider.deviceService = null;
+        tunnelProvider.mastershipService = null;
     }
 }
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java
index d2c4d5e..078deb1 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java
@@ -40,6 +40,7 @@
 import org.onosproject.incubator.net.tunnel.Tunnel;
 import org.onosproject.incubator.net.tunnel.TunnelId;
 import org.onosproject.incubator.net.tunnel.TunnelName;
+import org.onosproject.mastership.MastershipServiceAdapter;
 import org.onosproject.net.Annotations;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultAnnotations;
@@ -49,7 +50,10 @@
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceServiceAdapter;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
 
 /**
  * Test for PCEP setup tunnel.
@@ -62,12 +66,16 @@
     private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
     private final PcepControllerAdapter ctl = new PcepControllerAdapter();
     private final TunnelServiceAdapter  tunnelService = new TunnelServiceAdapter();
+    private final DeviceServiceAdapter  deviceService = new DeviceServiceAdapter();
+    private final MastershipServiceAdapter  mastershipService = new MastershipServiceAdapter();
 
     @Before
     public void setUp() throws IOException {
         tunnelProvider.tunnelProviderRegistry = registry;
         tunnelProvider.pcepClientController = controller;
         tunnelProvider.controller = ctl;
+        tunnelProvider.deviceService = deviceService;
+        tunnelProvider.mastershipService = mastershipService;
         tunnelProvider.cfgService = new ComponentConfigAdapter();
         tunnelProvider.tunnelService = tunnelService;
         tunnelProvider.activate();
@@ -111,6 +119,8 @@
         tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
                                    new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
                                    path, annotations);
+        controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
+                new ClientCapability(true, true, true, true, true));
 
         tunnelProvider.setupTunnel(tunnel, path);
         assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -154,6 +164,8 @@
         tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
                                    new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
                                    path, annotations);
+        controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010103))).setCapability(
+                new ClientCapability(true, true, true, true, true));
 
         tunnelProvider.setupTunnel(tunnel, path);
         assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
@@ -197,6 +209,8 @@
         tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
                                    new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
                                    path, annotations);
+        controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
+                new ClientCapability(true, true, true, true, true));
 
         tunnelProvider.setupTunnel(tunnel, path);
         assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -240,6 +254,8 @@
         tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
                                    new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
                                    path, annotations);
+        controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
+                new ClientCapability(true, true, true, true, true));
 
         tunnelProvider.setupTunnel(tunnel, path);
         assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -251,5 +267,7 @@
         tunnelProvider.controller = null;
         tunnelProvider.pcepClientController = null;
         tunnelProvider.tunnelProviderRegistry = null;
+        tunnelProvider.deviceService = null;
+        tunnelProvider.mastershipService = null;
     }
 }
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java
index 2abab75..ce00b5e 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java
@@ -24,27 +24,35 @@
 import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LSP_SIG_TYPE;
 import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCC_TUNNEL_ID;
 import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PLSP_ID;
+import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.DELEGATE;
 import static org.onosproject.provider.pcep.tunnel.impl.LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
 import static org.onosproject.pcep.controller.PcepSyncStatus.SYNCED;
-import static org.onosproject.pcep.controller.PcepSyncStatus.IN_SYNC;
+import static org.onosproject.net.Device.Type.ROUTER;
+import static org.onosproject.net.MastershipRole.MASTER;
 
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.onlab.packet.ChassisId;
 import org.onlab.packet.IpAddress;
 import org.onosproject.cfg.ComponentConfigAdapter;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.incubator.net.tunnel.DefaultTunnel;
 import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
 import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.incubator.net.tunnel.Tunnel.Type;
+import org.onosproject.incubator.net.tunnel.TunnelAdminService;
 import org.onosproject.incubator.net.tunnel.TunnelDescription;
 import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
 import org.onosproject.incubator.net.tunnel.TunnelId;
@@ -52,16 +60,26 @@
 import org.onosproject.incubator.net.tunnel.TunnelProvider;
 import org.onosproject.incubator.net.tunnel.TunnelProviderService;
 import org.onosproject.incubator.net.tunnel.Tunnel.State;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.AnnotationKeys;
 import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.ElementId;
+import org.onosproject.net.MastershipRole;
 import org.onosproject.net.Path;
 import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.provider.ProviderId;
 import org.onosproject.pcepio.exceptions.PcepOutOfBoundMessageException;
 import org.onosproject.pcepio.exceptions.PcepParseException;
 import org.onosproject.pcepio.protocol.PcepFactories;
 import org.onosproject.pcepio.protocol.PcepMessage;
 import org.onosproject.pcepio.protocol.PcepMessageReader;
+import org.onosproject.pcepio.protocol.PcepVersion;
 import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.LspKey;
 import org.onosproject.pcep.controller.PccId;
 
 import com.google.common.collect.ImmutableSet;
@@ -71,13 +89,73 @@
  */
 public class PcepTunnelAddedTest {
 
-    static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
+    public static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
+    public static final String UNKOWN = "UNKOWN";
     PcepTunnelProvider tunnelProvider = new PcepTunnelProvider();
     private final MockTunnelProviderRegistryAdapter registry = new MockTunnelProviderRegistryAdapter();
     private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
     private final PcepControllerAdapter ctl = new PcepControllerAdapter();
     private final PcepTunnelApiMapper pcepTunnelAPIMapper = new PcepTunnelApiMapper();
     private final MockTunnelServiceAdapter tunnelService = new MockTunnelServiceAdapter();
+    public final MockDeviceService deviceService = new MockDeviceService();
+    private final MockMasterShipService masterShipService = new MockMasterShipService();
+    private final MockTunnelAdminService tunnelAdminService = new MockTunnelAdminService();
+
+    private class MockTunnelAdminService implements TunnelAdminService {
+
+        @Override
+        public void removeTunnel(TunnelId tunnelId) {
+            // TODO Auto-generated method stub
+        }
+
+        @Override
+        public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, ProviderId producerName) {
+            // TODO Auto-generated method stub
+        }
+
+        @Override
+        public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, Type type, ProviderId producerName) {
+            // TODO Auto-generated method stub
+        }
+
+        @Override
+        public void updateTunnel(Tunnel tunnel, Path path) {
+            if (tunnelService.tunnelIdAsKeyStore.containsKey(tunnel.tunnelId())) {
+                tunnelService.tunnelIdAsKeyStore.replace(tunnel.tunnelId(), tunnel);
+            }
+        }
+    }
+
+    private class MockMasterShipService extends MastershipServiceAdapter {
+        boolean set;
+
+        private void setMaster(boolean isMaster) {
+            this.set = isMaster;
+        }
+
+        @Override
+        public MastershipRole getLocalRole(DeviceId deviceId) {
+            return set ? MastershipRole.MASTER : MastershipRole.STANDBY;
+        }
+
+        @Override
+        public boolean isLocalMaster(DeviceId deviceId) {
+            return getLocalRole(deviceId) == MASTER;
+        }
+    }
+
+    private class MockDeviceService extends DeviceServiceAdapter {
+        List<Device> devices = new LinkedList<>();
+
+        private void addDevice(Device dev) {
+            devices.add(dev);
+        }
+
+        @Override
+        public Iterable<Device> getAvailableDevices() {
+            return devices;
+        }
+    }
 
     private class MockTunnelProviderRegistryAdapter extends TunnelProviderRegistryAdapter {
         public long tunnelIdCounter;
@@ -97,12 +175,34 @@
 
             @Override
             public TunnelId tunnelAdded(TunnelDescription tunnel) {
-                return TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
+                TunnelId id = TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
+                Tunnel storedTunnel = new DefaultTunnel(ProviderId.NONE,
+                        tunnel.src(), tunnel.dst(),
+                        tunnel.type(),
+                        tunnel.groupId(),
+                        id,
+                        tunnel.tunnelName(),
+                        tunnel.path(),
+                        tunnel.resource(),
+                        tunnel.annotations());
+                tunnelService.tunnelIdAsKeyStore.put(id, storedTunnel);
+                return id;
             }
 
             @Override
             public TunnelId tunnelAdded(TunnelDescription tunnel, State state) {
-                return TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
+                TunnelId id = TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
+                Tunnel storedTunnel = new DefaultTunnel(ProviderId.NONE,
+                        tunnel.src(), tunnel.dst(),
+                        tunnel.type(),
+                        tunnel.groupId(),
+                        id,
+                        tunnel.tunnelName(),
+                        tunnel.path(),
+                        tunnel.resource(),
+                        tunnel.annotations());
+                tunnelService.tunnelIdAsKeyStore.put(id, storedTunnel);
+                return id;
             }
 
             @Override
@@ -168,9 +268,12 @@
         tunnelProvider.tunnelProviderRegistry = registry;
         tunnelProvider.pcepClientController = controller;
         tunnelProvider.controller = ctl;
+        tunnelProvider.deviceService = deviceService;
+        tunnelProvider.mastershipService = masterShipService;
         tunnelProvider.pcepTunnelApiMapper = pcepTunnelAPIMapper;
         tunnelProvider.cfgService = new ComponentConfigAdapter();
         tunnelProvider.tunnelService = tunnelService;
+        tunnelProvider.tunnelAdminService = tunnelAdminService;
         tunnelProvider.service = registry.register(tunnelProvider);
         tunnelProvider.activate();
     }
@@ -210,6 +313,19 @@
 
         PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
         PcepMessage message = reader.readFrom(buffer);
+
+        DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
+        newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
+        newBuilder.set(AnnotationKeys.TYPE, "L3");
+        Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
+                UNKOWN, UNKOWN, UNKOWN,
+                UNKOWN, new ChassisId(),
+                newBuilder.build());
+
+        deviceService.addDevice(device);
+        controller.getClient(PccId.pccId(IpAddress.valueOf("1.1.1.1"))).setCapability(
+                new ClientCapability(true, true, true, true, true));
+        masterShipService.setMaster(true);
         controller.processClientMessage(PccId.pccId(IpAddress.valueOf("1.1.1.1")), message);
 
         assertThat(registry.tunnelIdCounter, is((long) 1));
@@ -254,14 +370,20 @@
                 .set(LSP_SIG_TYPE, WITHOUT_SIGNALLING_AND_WITHOUT_SR.name())
                 .set(PCC_TUNNEL_ID, String.valueOf(1))
                 .set(PLSP_ID, String.valueOf(1))
-                .set(LOCAL_LSP_ID, String.valueOf(1)).build();
+                .set(LOCAL_LSP_ID, String.valueOf(1))
+                .set(DELEGATE, String.valueOf("true"))
+                .build();
 
         Tunnel tunnel = new DefaultTunnel(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, INIT, null, null,
                                           TunnelName.tunnelName("T123"), null, annotations);
         tunnelService.setupTunnel(null, null, tunnel, null);
 
         PccId pccId = PccId.pccId(IpAddress.valueOf(0x4e1f0400));
-        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
+        PcepClientAdapter pc = new PcepClientAdapter();
+        pc.init(pccId, PcepVersion.PCEP_1);
+        masterShipService.setMaster(true);
+        controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
         controller.getClient(pccId).setLspDbSyncStatus(SYNCED);
 
         // Process update message.
@@ -281,6 +403,164 @@
                                        0x00, 0x00, 0x00, 0x00,
                                        0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
                                        0x00, 0x00, 0x00, 0x02,
+                                       0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x1B, // LSP object
+                                       0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
+                                       0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+                                       0x01, 0x01, 0x01, 0x01,
+                                       0x00, 0x01, 0x00, 0x01,
+                                       0x01, 0x01, 0x01, 0x01,
+                                       0x05, 0x05, 0x05, 0x05,
+
+                                       0x07, 0x10, 0x00, 0x14, //ERO object
+                                       0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+                                       0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+                                       0x08, 0x10, 0x00, 0x34, //RRO object
+                                       0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+                                       0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+                                       0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+                                       0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+                                       0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+                                       0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+                                       };
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(reportMsg);
+
+        PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
+        PcepMessage message = reader.readFrom(buffer);
+
+        DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
+        newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
+        newBuilder.set(AnnotationKeys.TYPE, "L3");
+        Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
+                UNKOWN, UNKOWN, UNKOWN,
+                UNKOWN, new ChassisId(),
+                newBuilder.build());
+
+        deviceService.addDevice(device);
+
+        PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
+        controller.getClient(pccId).setLspDbSyncStatus(SYNCED);
+        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
+        PcepClientAdapter pc = new PcepClientAdapter();
+        pc.init(pccId, PcepVersion.PCEP_1);
+        controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+        masterShipService.setMaster(true);
+        controller.processClientMessage(pccId, message);
+
+        assertThat(registry.tunnelIdCounter, is((long) 1));
+    }
+
+    /**
+     * Tests PCRpt msg with D flag set and delegated to non-master.
+     *
+     * @throws InterruptedException while waiting for delay
+     */
+    @Test
+    public void tunnelProviderAddedTest4() throws PcepParseException, PcepOutOfBoundMessageException,
+            InterruptedException {
+        byte[] reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+                0x21, 0x10, 0x00, 0x14,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x01, //SRP object
+                0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+                0x00, 0x00, 0x00, 0x02,
+                0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x02, //LSP object
+                0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, //symbolic path tlv
+                0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+                0x01, 0x01, 0x01, 0x01,
+                0x00, 0x01, 0x00, 0x01,
+                0x01, 0x01, 0x01, 0x01,
+                0x05, 0x05, 0x05, 0x05,
+
+                0x07, 0x10, 0x00, 0x14, //ERO object
+                0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+                0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+                0x08, 0x10, 0x00, 0x34, //RRO object
+                0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+                0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+                0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+                0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+                0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+                0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+                };
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(reportMsg);
+
+        PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
+        PcepMessage message = reader.readFrom(buffer);
+
+        //PCC 1.1.1.1, D=0, ONOS as master
+        masterShipService.setMaster(true);
+        DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
+        newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
+        newBuilder.set(AnnotationKeys.TYPE, "L3");
+        Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
+                UNKOWN, UNKOWN, UNKOWN,
+                UNKOWN, new ChassisId(),
+                newBuilder.build());
+
+        deviceService.addDevice(device);
+        controller.getClient(PccId.pccId(IpAddress.valueOf("1.1.1.1"))).setCapability(
+                new ClientCapability(true, true, true, true, true));
+        controller.processClientMessage(PccId.pccId(IpAddress.valueOf("1.1.1.1")), message);
+        assertThat(tunnelService.tunnelIdAsKeyStore.values().iterator().next().annotations().value(DELEGATE),
+                is("false"));
+
+        //PCC 1.1.1.1, D=1, non-master
+        masterShipService.setMaster(false);
+
+        reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+                0x21, 0x10, 0x00, 0x14,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x01, //SRP object
+                0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+                0x00, 0x00, 0x00, 0x02,
+                0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x03, //LSP object
+                0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, //symbolic path tlv
+                0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+                0x01, 0x01, 0x01, 0x01,
+                0x00, 0x01, 0x00, 0x01,
+                0x01, 0x01, 0x01, 0x01,
+                0x05, 0x05, 0x05, 0x05,
+
+                0x07, 0x10, 0x00, 0x14, //ERO object
+                0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+                0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+                0x08, 0x10, 0x00, 0x34, //RRO object
+                0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+                0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+                0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+                0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+                0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+                0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+                };
+
+        buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(reportMsg);
+
+        reader = PcepFactories.getGenericReader();
+        message = reader.readFrom(buffer);
+
+        controller.processClientMessage(PccId.pccId(IpAddress.valueOf("1.1.1.1")), message);
+        TimeUnit.MILLISECONDS.sleep(4000);
+        assertThat(registry.tunnelIdCounter, is((long) 1));
+        assertThat(tunnelService.tunnelIdAsKeyStore.values().iterator().next().annotations().value(DELEGATE),
+                is("true"));
+    }
+
+    /**
+     * Tests adding PCC Init LSP after LSP DB sync is over.
+     */
+    @Test
+    public void tunnelProviderAddedTest5() throws PcepParseException, PcepOutOfBoundMessageException {
+        byte[] reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+                                       0x21, 0x10, 0x00, 0x14, //SRP object
+                                       0x00, 0x00, 0x00, 0x00,
+                                       0x00, 0x00, 0x00, 0x00,
+                                       0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+                                       0x00, 0x00, 0x00, 0x02,
                                        0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x19, // LSP object
                                        0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
                                        0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
@@ -308,290 +588,27 @@
         PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
         PcepMessage message = reader.readFrom(buffer);
 
+        DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
+        newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
+        newBuilder.set(AnnotationKeys.TYPE, "L3");
+        Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
+                UNKOWN, UNKOWN, UNKOWN,
+                UNKOWN, new ChassisId(),
+                newBuilder.build());
+
+        deviceService.addDevice(device);
+
         PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
         controller.getClient(pccId).setLspDbSyncStatus(SYNCED);
-        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
+        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
+        PcepClientAdapter pc = new PcepClientAdapter();
+        pc.init(pccId, PcepVersion.PCEP_1);
+        controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+        masterShipService.setMaster(true);
         controller.processClientMessage(pccId, message);
 
-        assertThat(registry.tunnelIdCounter, is((long) 1));
-    }
-
-    /**
-     * Tests LSPDB sync where PCC reports less LSPs than known by PCE and PCE deletes at the end of DB sync.
-     */
-    @Test
-    public void testCaseLspDbSync1() throws PcepParseException, PcepOutOfBoundMessageException {
-        /* Step 1 create 2 LSPs */
-        byte[] reportMsg1 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
-                                       0x21, 0x10, 0x00, 0x14, //SRP object
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x19, // LSP object
-                                       0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
-                                       0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
-                                       0x01, 0x01, 0x01, 0x01,
-                                       0x00, 0x01, 0x00, 0x01,
-                                       0x01, 0x01, 0x01, 0x01,
-                                       0x05, 0x05, 0x05, 0x05,
-
-                                       0x07, 0x10, 0x00, 0x14, //ERO object
-                                       0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
-                                       0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
-                                       0x08, 0x10, 0x00, 0x34, //RRO object
-                                       0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
-                                       0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                       0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
-                                       0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                       0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
-                                       0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
-                                       };
-
-        ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer();
-        buffer1.writeBytes(reportMsg1);
-
-        PcepMessageReader<PcepMessage> reader1 = PcepFactories.getGenericReader();
-        PcepMessage message1 = reader1.readFrom(buffer1);
-
-        PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
-        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
-        controller.processClientMessage(pccId, message1);
-
-        /* create 2nd LSP */
-        byte[] reportMsg2 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
-                                       0x21, 0x10, 0x00, 0x14, //SRP object
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x20, 0x19, // LSP object
-                                       0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
-                                       0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
-                                       0x01, 0x01, 0x01, 0x01,
-                                       0x00, 0x02, 0x00, 0x02,
-                                       0x01, 0x01, 0x01, 0x01,
-                                       0x05, 0x05, 0x05, 0x05,
-
-                                       0x07, 0x10, 0x00, 0x14, //ERO object
-                                       0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
-                                       0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
-                                       0x08, 0x10, 0x00, 0x34, //RRO object
-                                       0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
-                                       0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                       0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
-                                       0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                       0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
-                                       0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
-                                       };
-
-        ChannelBuffer buffer2 = ChannelBuffers.dynamicBuffer();
-        buffer2.writeBytes(reportMsg2);
-
-        PcepMessageReader<PcepMessage> reader2 = PcepFactories.getGenericReader();
-        PcepMessage message2 = reader2.readFrom(buffer2);
-
-        controller.processClientMessage(pccId, message2);
-
-        /* Assert number of LSPs in DB to be 2. */
-        assertThat(registry.tunnelIdCounter, is((long) 2));
-
-        /* Step 2 send sync begin message and LSP 1. */
-        byte[] reportMsg3 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
-                                        0x21, 0x10, 0x00, 0x14, //SRP object
-                                        0x00, 0x00, 0x00, 0x00,
-                                        0x00, 0x00, 0x00, 0x00,
-                                        0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
-                                        0x00, 0x00, 0x00, 0x00,
-                                        0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x1B, // LSP object
-                                        0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
-                                        0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
-                                        0x01, 0x01, 0x01, 0x01,
-                                        0x00, 0x01, 0x00, 0x01,
-                                        0x01, 0x01, 0x01, 0x01,
-                                        0x05, 0x05, 0x05, 0x05,
-
-                                        0x07, 0x10, 0x00, 0x14, //ERO object
-                                        0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
-                                        0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
-                                        0x08, 0x10, 0x00, 0x34, //RRO object
-                                        0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
-                                        0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                        0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
-                                        0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                        0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
-                                        0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
-                                        };
-
-         ChannelBuffer buffer3 = ChannelBuffers.dynamicBuffer();
-         buffer3.writeBytes(reportMsg3);
-         PcepMessageReader<PcepMessage> reader3 = PcepFactories.getGenericReader();
-         PcepMessage message3 = reader3.readFrom(buffer3);
-         controller.processClientMessage(pccId, message3);
-
-         assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(IN_SYNC));
-
-        /* Step 3 send end of sync marker */
-         byte[] reportMsg4 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x24,
-                                         0x20, 0x10, 0x00, 0x1C, // LSP object
-                                         0x00, 0x00, 0x10, 0x19,
-                                         0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
-                                         0x00, 0x00, 0x00, 0x00,
-                                         0x00, 0x00, 0x00, 0x00,
-                                         0x00, 0x00, 0x00, 0x00,
-                                         0x00, 0x00, 0x00, 0x00,
-                                         0x07, 0x10, 0x00, 0x04, //ERO object
-                                         };
-
-          ChannelBuffer buffer4 = ChannelBuffers.dynamicBuffer();
-          buffer4.writeBytes(reportMsg4);
-          PcepMessageReader<PcepMessage> reader4 = PcepFactories.getGenericReader();
-          PcepMessage message4 = reader4.readFrom(buffer4);
-          controller.processClientMessage(pccId, message4);
-
-        assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(SYNCED));
-    }
-
-    /**
-     * Tests PCC PCRpt PCE initiated LSP which PCE doesn't know and hence should send PCInit delete msg.
-     */
-    @Test
-    public void testCaseLspDbSync2() throws PcepParseException, PcepOutOfBoundMessageException {
-        /* Step 1 create 2 LSPs */
-        byte[] reportMsg1 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
-                                       0x21, 0x10, 0x00, 0x14, //SRP object
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x19, // LSP object
-                                       0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
-                                       0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
-                                       0x01, 0x01, 0x01, 0x01,
-                                       0x00, 0x01, 0x00, 0x01,
-                                       0x01, 0x01, 0x01, 0x01,
-                                       0x05, 0x05, 0x05, 0x05,
-
-                                       0x07, 0x10, 0x00, 0x14, //ERO object
-                                       0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
-                                       0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
-                                       0x08, 0x10, 0x00, 0x34, //RRO object
-                                       0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
-                                       0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                       0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
-                                       0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                       0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
-                                       0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
-                                       };
-
-        ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer();
-        buffer1.writeBytes(reportMsg1);
-
-        PcepMessageReader<PcepMessage> reader1 = PcepFactories.getGenericReader();
-        PcepMessage message1 = reader1.readFrom(buffer1);
-
-        PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
-        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
-        controller.processClientMessage(pccId, message1);
-
-        /* create 2nd LSP */
-        byte[] reportMsg2 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
-                                       0x21, 0x10, 0x00, 0x14, //SRP object
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x20, 0x19, // LSP object
-                                       0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
-                                       0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
-                                       0x01, 0x01, 0x01, 0x01,
-                                       0x00, 0x02, 0x00, 0x02,
-                                       0x01, 0x01, 0x01, 0x01,
-                                       0x05, 0x05, 0x05, 0x05,
-
-                                       0x07, 0x10, 0x00, 0x14, //ERO object
-                                       0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
-                                       0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
-                                       0x08, 0x10, 0x00, 0x34, //RRO object
-                                       0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
-                                       0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                       0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
-                                       0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                       0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
-                                       0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
-                                       };
-
-        ChannelBuffer buffer2 = ChannelBuffers.dynamicBuffer();
-        buffer2.writeBytes(reportMsg2);
-
-        PcepMessageReader<PcepMessage> reader2 = PcepFactories.getGenericReader();
-        PcepMessage message2 = reader2.readFrom(buffer2);
-
-        controller.processClientMessage(pccId, message2);
-
-        /* Assert number of LSPs in DB to be 2. */
-        assertThat(registry.tunnelIdCounter, is((long) 2));
-
-        /* Step 2 send sync begin message and LSP 1. */
-        byte[] reportMsg3 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
-                                        0x21, 0x10, 0x00, 0x14, //SRP object
-                                        0x00, 0x00, 0x00, 0x00,
-                                        0x00, 0x00, 0x00, 0x00,
-                                        0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
-                                        0x00, 0x00, 0x00, 0x00,
-                                        0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, (byte) 0x9B, // LSP object
-                                        0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
-                                        0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
-                                        0x01, 0x01, 0x01, 0x01,
-                                        0x00, 0x01, 0x00, 0x03,
-                                        0x01, 0x01, 0x01, 0x01,
-                                        0x05, 0x05, 0x05, 0x05,
-
-                                        0x07, 0x10, 0x00, 0x14, //ERO object
-                                        0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
-                                        0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
-                                        0x08, 0x10, 0x00, 0x34, //RRO object
-                                        0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
-                                        0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                        0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
-                                        0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
-                                        0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
-                                        0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
-                                        };
-
-        ChannelBuffer buffer3 = ChannelBuffers.dynamicBuffer();
-        buffer3.writeBytes(reportMsg3);
-        PcepMessageReader<PcepMessage> reader3 = PcepFactories.getGenericReader();
-        PcepMessage message3 = reader3.readFrom(buffer3);
-        controller.processClientMessage(pccId, message3);
-
-        assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(IN_SYNC));
-
-        /* Step 3 send end of sync marker */
-        byte[] reportMsg4 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x24,
-                                       0x20, 0x10, 0x00, 0x1C, // LSP object
-                                       0x00, 0x00, 0x10, 0x19,
-                                       0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x00, 0x00, 0x00, 0x00,
-                                       0x07, 0x10, 0x00, 0x04, //ERO object
-                                       };
-
-        ChannelBuffer buffer4 = ChannelBuffers.dynamicBuffer();
-        buffer4.writeBytes(reportMsg4);
-        PcepMessageReader<PcepMessage> reader4 = PcepFactories.getGenericReader();
-        PcepMessage message4 = reader4.readFrom(buffer4);
-        controller.processClientMessage(pccId, message4);
-
-        assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(SYNCED));
+        assertThat(registry.tunnelIdCounter, is((long) 0));
     }
 
     @After
@@ -604,6 +621,9 @@
         tunnelProvider.pcepTunnelApiMapper = null;
         tunnelProvider.cfgService = null;
         tunnelProvider.tunnelService = null;
+        tunnelProvider.tunnelAdminService = null;
+        tunnelProvider.deviceService = null;
+        tunnelProvider.mastershipService = null;
         tunnelProvider.service = null;
     }
 }
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java
index 2922537..e641c64 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java
@@ -35,6 +35,7 @@
 import org.onosproject.incubator.net.tunnel.Tunnel;
 import org.onosproject.incubator.net.tunnel.TunnelId;
 import org.onosproject.incubator.net.tunnel.TunnelName;
+import org.onosproject.mastership.MastershipServiceAdapter;
 import org.onosproject.net.Annotations;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultAnnotations;
@@ -44,7 +45,10 @@
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceServiceAdapter;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
 import org.onosproject.cfg.ComponentConfigAdapter;
 
 public class PcepTunnelProviderTest {
@@ -55,6 +59,8 @@
     private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
     private final PcepControllerAdapter ctl = new PcepControllerAdapter();
     private final TunnelServiceAdapter  tunnelService = new TunnelServiceAdapter();
+    private final DeviceServiceAdapter  deviceService = new DeviceServiceAdapter();
+    private final MastershipServiceAdapter  mastershipService = new MastershipServiceAdapter();
 
     @Test
     public void testCasePcepSetupTunnel() {
@@ -62,6 +68,8 @@
         tunnelProvider.tunnelProviderRegistry = registry;
         tunnelProvider.pcepClientController = controller;
         tunnelProvider.controller = ctl;
+        tunnelProvider.deviceService = deviceService;
+        tunnelProvider.mastershipService = mastershipService;
         tunnelProvider.cfgService = new ComponentConfigAdapter();
         tunnelProvider.tunnelService = tunnelService;
         tunnelProvider.activate();
@@ -99,6 +107,8 @@
         tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
                                    new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
                                    path, annotations);
+        controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
+                new ClientCapability(true, true, true, true, true));
 
         tunnelProvider.setupTunnel(tunnel, path);
 
@@ -109,6 +119,8 @@
     public void tearDown() throws IOException {
         tunnelProvider.deactivate();
         tunnelProvider.controller = null;
+        tunnelProvider.deviceService = null;
+        tunnelProvider.mastershipService = null;
         tunnelProvider.pcepClientController = null;
         tunnelProvider.tunnelProviderRegistry = null;
     }
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java
index 2c9961f..4106dfb 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java
@@ -47,6 +47,10 @@
 import org.onosproject.net.Path;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.LspKey;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcepio.protocol.PcepVersion;
 import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
 
 import static org.onosproject.provider.pcep.tunnel.impl.LspType.WITH_SIGNALLING;
@@ -99,7 +103,7 @@
 
         ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
 
-        ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
+        ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
 
         Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
                 .type(Link.Type.DIRECT).build();
@@ -108,6 +112,8 @@
         path = new DefaultPath(pid, links, 20, EMPTY);
 
         Annotations annotations = DefaultAnnotations.builder()
+                .set(PcepAnnotationKeys.PLSP_ID, "1")
+                .set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
                 .set(LSP_SIG_TYPE, WITH_SIGNALLING.name())
                 .build();
 
@@ -124,6 +130,12 @@
 
         tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
 
+        PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
+        PcepClientAdapter pc = new PcepClientAdapter();
+        pc.init(pccId, PcepVersion.PCEP_1);
+        controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
         tunnelProvider.updateTunnel(tunnel, path);
         assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
     }
@@ -137,7 +149,7 @@
         Path path;
         ProviderId pid = new ProviderId("pcep", PROVIDER_ID);
         List<Link> links = new ArrayList<>();
-        IpAddress srcIp = IpAddress.valueOf(0xC010103);
+        IpAddress srcIp = IpAddress.valueOf(0xD010101);
         IpElementId srcElementId = IpElementId.ipElement(srcIp);
 
         IpAddress dstIp = IpAddress.valueOf(0xD010102);
@@ -151,7 +163,7 @@
 
         ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
 
-        ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
+        ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
 
         Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
                 .type(Link.Type.DIRECT).build();
@@ -161,6 +173,8 @@
 
         Annotations annotations = DefaultAnnotations.builder()
                 .set(LSP_SIG_TYPE, WITH_SIGNALLING.name())
+                .set(PcepAnnotationKeys.PLSP_ID, "1")
+                .set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
                 .build();
 
         tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
@@ -176,6 +190,12 @@
 
         tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
 
+        PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
+        PcepClientAdapter pc = new PcepClientAdapter();
+        pc.init(pccId, PcepVersion.PCEP_1);
+        controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
         tunnelProvider.updateTunnel(tunnel, path);
         assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
     }
@@ -203,7 +223,7 @@
 
         ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
 
-        ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
+        ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
 
         Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
                 .type(Link.Type.DIRECT).build();
@@ -213,6 +233,8 @@
 
         Annotations annotations = DefaultAnnotations.builder()
                 .set(LSP_SIG_TYPE, SR_WITHOUT_SIGNALLING.name())
+                .set(PcepAnnotationKeys.PLSP_ID, "1")
+                .set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
                 .build();
 
         tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
@@ -228,6 +250,12 @@
 
         tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
 
+        PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
+        PcepClientAdapter pc = new PcepClientAdapter();
+        pc.init(pccId, PcepVersion.PCEP_1);
+        controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
         tunnelProvider.updateTunnel(tunnel, path);
         assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
     }
@@ -255,7 +283,7 @@
 
         ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
 
-        ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
+        ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
 
         Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
                 .type(Link.Type.DIRECT).build();
@@ -265,6 +293,8 @@
 
         Annotations annotations = DefaultAnnotations.builder()
                 .set(LSP_SIG_TYPE, WITHOUT_SIGNALLING_AND_WITHOUT_SR.name())
+                .set(PcepAnnotationKeys.PLSP_ID, "1")
+                .set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
                 .build();
 
         tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
@@ -280,6 +310,12 @@
 
         tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
 
+        PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
+        PcepClientAdapter pc = new PcepClientAdapter();
+        pc.init(pccId, PcepVersion.PCEP_1);
+        controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
         tunnelProvider.updateTunnel(tunnel, path);
         assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
     }