[ONOS-4167] Identify the impacted tunnels based on network events, notify to PCE app and trigger MBB flow.

Change-Id: I1766f4afbc0ee2f4c05c75cf788c91f9df8aaa9a
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/BasicPceccHandlerTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/BasicPceccHandlerTest.java
index 8c3de14..cd28f9e 100644
--- a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/BasicPceccHandlerTest.java
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/BasicPceccHandlerTest.java
@@ -19,7 +19,6 @@
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.nullValue;
-
 import static org.onosproject.net.Link.Type.DIRECT;
 
 import java.util.Iterator;
@@ -29,7 +28,6 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-
 import org.onlab.packet.IpAddress;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
@@ -165,6 +163,7 @@
 
     @After
     public void tearDown() throws Exception {
+        PceManagerTest.flowsDownloaded = 0;
     }
 
     /**
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java
index 5b0d869..b022d9a 100644
--- a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java
@@ -129,7 +129,7 @@
     private Device deviceD1, deviceD2, deviceD3, deviceD4;
     private Device pcepDeviceD1, pcepDeviceD2, pcepDeviceD3, pcepDeviceD4;
     private Link link1, link2, link3, link4;
-    private static int flowsDownloaded;
+    protected static int flowsDownloaded;
     private TunnelListener tunnelListener;
 
     @Before
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceccSrTeBeHandlerTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceccSrTeBeHandlerTest.java
index 2a419b5..a49bb0b 100644
--- a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceccSrTeBeHandlerTest.java
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceccSrTeBeHandlerTest.java
@@ -158,6 +158,7 @@
 
     @After
     public void tearDown() throws Exception {
+        PceManagerTest.flowsDownloaded = 0;
     }
 
     /**
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/LspKey.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/LspKey.java
new file mode 100644
index 0000000..5dee845
--- /dev/null
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/LspKey.java
@@ -0,0 +1,85 @@
+/*
+ * 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.pcep.controller;
+
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Representation of LSP info, it will be unique for each LSP.
+ */
+public class LspKey {
+    private int plspId;
+    private short localLspId;
+
+    /**
+     * Creates new instance of LspInfo.
+     *
+     * @param plspId LSP id assigned per tunnel per session
+     * @param localLspId LSP id assigned per tunnel
+     */
+    public LspKey(int plspId, short localLspId) {
+        this.plspId = plspId;
+        this.localLspId = localLspId;
+    }
+
+    /**
+     * Obtains PLSP id.
+     *
+     * @return LSP id assigned per tunnel per session
+     */
+    public int plspId() {
+        return plspId;
+    }
+
+    /**
+     * Obtains local LSP id.
+     *
+     * @return LSP id assigned per tunnel
+     */
+    public short localLspId() {
+        return localLspId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(plspId, localLspId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof LspKey) {
+            LspKey other = (LspKey) obj;
+            return Objects.equals(plspId, other.plspId)
+                    && Objects.equals(localLspId, other.localLspId);
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("plspId", plspId)
+                .add("localLspId", localLspId)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java
index 6ab804c..297d71e 100644
--- a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java
@@ -149,4 +149,20 @@
      * @param pccId PCEP client ID
      */
     void deleteNode(PccId pccId);
+
+     /**
+     * Sets D flag for the given LSP and its LSP info.
+     *
+     * @param lspKey contains LSP info
+     * @param dFlag delegation flag in LSP object
+     */
+    void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag);
+
+    /**
+     * Returns delegation flag for the given LSP info.
+     *
+     * @param lspKey contains LSP info
+     * @return delegation flag
+     */
+    Boolean delegationInfo(LspKey lspKey);
 }
diff --git a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java
index 6f2d8fd..ac51371 100644
--- a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java
+++ b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java
@@ -20,11 +20,13 @@
 import java.net.SocketAddress;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.RejectedExecutionException;
 
 import org.jboss.netty.channel.Channel;
 import org.onlab.packet.IpAddress;
 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.PcepPacketStats;
@@ -67,6 +69,7 @@
     private byte deadTime;
     private byte sessionId;
     private PcepPacketStatsImpl pktStats;
+    private Map<LspKey, Boolean> lspDelegationInfo;
 
     @Override
     public void init(PccId pccId, PcepVersion pcepVersion, PcepPacketStats pktStats) {
@@ -241,6 +244,16 @@
     }
 
     @Override
+    public void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag) {
+        lspDelegationInfo.put(lspKey, dFlag);
+    }
+
+    @Override
+    public Boolean delegationInfo(LspKey lspKey) {
+        return lspDelegationInfo.get(lspKey);
+    }
+
+    @Override
     public boolean isOptical() {
         return false;
     }
diff --git a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java
old mode 100755
new mode 100644
index b8e108e..b8d2695
--- a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java
+++ b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java
@@ -29,14 +29,14 @@
      *
      * @return bandwidth value
      */
-    int getBandwidth();
+    float getBandwidth();
 
     /**
      * Sets bandwidth with specified value.
      *
      * @param iBandwidth Bandwidth's value
      */
-    void setBandwidth(int iBandwidth);
+    void setBandwidth(float iBandwidth);
 
     /**
      * Writes the BandwidthObject into channel buffer.
diff --git a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java
index 3621572..83973b4 100644
--- a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java
+++ b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java
@@ -51,6 +51,7 @@
     public static final byte BANDWIDTH_OBJ_TYPE = 1;
     public static final byte BANDWIDTH_OBJ_CLASS = 5;
     public static final byte BANDWIDTH_OBJECT_VERSION = 1;
+    public static final int NO_OF_BITS = 8;
     public static final short BANDWIDTH_OBJ_MINIMUM_LENGTH = 8;
 
     static final PcepObjectHeader DEFAULT_BANDWIDTH_OBJECT_HEADER = new PcepObjectHeader(BANDWIDTH_OBJ_CLASS,
@@ -58,7 +59,7 @@
             BANDWIDTH_OBJ_MINIMUM_LENGTH);
 
     private PcepObjectHeader bandwidthObjHeader;
-    private int iBandwidth;
+    private float iBandwidth;
 
     /**
      * Constructor to bandwidth object header and bandwidth.
@@ -66,7 +67,7 @@
      * @param bandwidthObjHeader bandwidth object header
      * @param iBandwidth bandwidth value
      */
-    public PcepBandwidthObjectVer1(PcepObjectHeader bandwidthObjHeader, int iBandwidth) {
+    public PcepBandwidthObjectVer1(PcepObjectHeader bandwidthObjHeader, float iBandwidth) {
         this.bandwidthObjHeader = bandwidthObjHeader;
         this.iBandwidth = iBandwidth;
     }
@@ -76,7 +77,7 @@
      *
      * @param iBandwidth bandwidth value
      */
-    public PcepBandwidthObjectVer1(int iBandwidth) {
+    public PcepBandwidthObjectVer1(float iBandwidth) {
         this.bandwidthObjHeader = DEFAULT_BANDWIDTH_OBJECT_HEADER;
         this.iBandwidth = iBandwidth;
     }
@@ -100,12 +101,12 @@
     }
 
     @Override
-    public int getBandwidth() {
+    public float getBandwidth() {
         return this.iBandwidth;
     }
 
     @Override
-    public void setBandwidth(int iBandwidth) {
+    public void setBandwidth(float iBandwidth) {
         this.iBandwidth = iBandwidth;
     }
 
@@ -119,12 +120,25 @@
     public static PcepBandwidthObject read(ChannelBuffer cb) throws PcepParseException {
 
         PcepObjectHeader bandwidthObjHeader;
-        int iBandwidth;
+        float bandwidth;
 
         bandwidthObjHeader = PcepObjectHeader.read(cb);
-        iBandwidth = cb.readInt();
+        bandwidth = ieeeToFloatRead(cb.readInt()) * NO_OF_BITS;
 
-        return new PcepBandwidthObjectVer1(bandwidthObjHeader, iBandwidth);
+        return new PcepBandwidthObjectVer1(bandwidthObjHeader, bandwidth);
+    }
+
+    /**
+     * Parse the IEEE floating point notation and returns it in normal float.
+     *
+     * @param iVal IEEE floating point number
+     * @return normal float
+     */
+    public static float ieeeToFloatRead(int iVal) {
+        iVal = (((iVal & 0xFF) << 24) | ((iVal & 0xFF00) << 8)
+                | ((iVal & 0xFF0000) >> 8) | ((iVal >> 24) & 0xFF));
+
+        return Float.intBitsToFloat(iVal);
     }
 
     @Override
@@ -138,7 +152,7 @@
             throw new PcepParseException("Failed to write bandwidth object header. Index " + objLenIndex);
         }
 
-        cb.writeInt(iBandwidth);
+        cb.writeInt(Float.floatToIntBits(iBandwidth));
         short hLength = (short) (cb.writerIndex() - objStartIndex);
         cb.setShort(objLenIndex, hLength);
         //will be helpful during print().
diff --git a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java
index 4b97d05..d680ff4 100644
--- a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java
+++ b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java
@@ -16,8 +16,10 @@
 
 package org.onosproject.pcepio.protocol.ver1;
 
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.ListIterator;
+import java.util.Objects;
 
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.onosproject.pcepio.exceptions.PcepParseException;
@@ -399,10 +401,47 @@
     }
 
     @Override
+    public int hashCode() {
+        return Objects.hash(eroObjHeader, subObjectList);
+    }
+
+    @Override
     public String toString() {
         return MoreObjects.toStringHelper(getClass()).omitNullValues()
                 .add("EroObjHeader", eroObjHeader)
                 .add("SubObjects", subObjectList)
                 .toString();
     }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof PcepEroObjectVer1) {
+            int countObjSubTlv = 0;
+            int countOtherSubTlv = 0;
+            boolean isCommonSubTlv = true;
+            PcepEroObjectVer1 other = (PcepEroObjectVer1) obj;
+            Iterator<PcepValueType> objListIterator = other.subObjectList.iterator();
+            countOtherSubTlv = other.subObjectList.size();
+            countObjSubTlv = subObjectList.size();
+            if (countObjSubTlv != countOtherSubTlv) {
+                return false;
+            } else {
+                while (objListIterator.hasNext() && isCommonSubTlv) {
+                    PcepValueType subTlv = objListIterator.next();
+                    if (subObjectList.contains(subTlv)) {
+                        isCommonSubTlv = Objects.equals(subObjectList.get(subObjectList.indexOf(subTlv)),
+                                         other.subObjectList.get(other.subObjectList.indexOf(subTlv)));
+                    } else {
+                        isCommonSubTlv = false;
+                    }
+                }
+                return isCommonSubTlv && Objects.equals(eroObjHeader, other.eroObjHeader);
+            }
+        }
+        return false;
+    }
 }
diff --git a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepObjectHeader.java b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepObjectHeader.java
index cfe2fe3..7062076 100644
--- a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepObjectHeader.java
+++ b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepObjectHeader.java
@@ -16,6 +16,8 @@
 
 package org.onosproject.pcepio.types;
 
+import java.util.Objects;
+
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -212,6 +214,27 @@
     }
 
     @Override
+    public int hashCode() {
+        return Objects.hash(objClass, objType, bPFlag, bIFlag, objLen);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PcepObjectHeader) {
+            PcepObjectHeader other = (PcepObjectHeader) obj;
+            return Objects.equals(objClass, other.objClass)
+                    && Objects.equals(objType, other.objType)
+                    && Objects.equals(bPFlag, other.bPFlag)
+                    && Objects.equals(bIFlag, other.bIFlag)
+                    && Objects.equals(objLen, other.objLen);
+        }
+        return false;
+    }
+
+    @Override
     public String toString() {
         return MoreObjects.toStringHelper(getClass())
                 .add("ObjectClass", objClass)
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
index 034deaa..8f9c3c4 100644
--- 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
@@ -17,12 +17,15 @@
 
 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;
@@ -45,6 +48,7 @@
     private PcepVersion pcepVersion;
     private PcepSyncStatus lspDbSyncStatus;
     private PcepSyncStatus labelDbSyncStatus;
+    private Map<LspKey, Boolean> lspDelegationInfo = new HashMap<>();
 
     /**
      * Initialize instance with specified parameters.
@@ -147,4 +151,14 @@
     @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);
+    }
 }
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..fbfeda7 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,6 +73,7 @@
 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;
@@ -109,6 +115,9 @@
 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;
@@ -126,6 +135,7 @@
 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.RequestType.CREATE;
 import static org.onosproject.provider.pcep.tunnel.impl.RequestType.DELETE;
 import static org.onosproject.provider.pcep.tunnel.impl.RequestType.LSP_STATE_RPT;
@@ -148,6 +158,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 +186,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>();
@@ -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) {
@@ -1226,27 +1305,19 @@
             }
         }
 
-        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) {
+            SparseAnnotations annotations = DefaultAnnotations.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;
+        }
 
-            int 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();
+        private LspType getLspType(PcepSrpObject srpObj) {
             LspType lspType = WITH_SIGNALLING;
 
             if (null != srpObj) {
@@ -1266,6 +1337,31 @@
                     }
                 }
             }
+            return lspType;
+        }
+
+        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);
+
+            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 +1383,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 +1398,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 +1424,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 +1432,7 @@
             }
 
             DefaultTunnelDescription td;
+            SparseAnnotations annotations = null;
             State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
             if (tunnel == null) {
                 if (lspObj.getRFlag()) {
@@ -1345,21 +1448,15 @@
                      * 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();
+                    annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType);
 
-                    // Gnenerate tunnel id for the temporary tunnel.
+                    // Generate 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);
-
                     /*
                      * 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.
@@ -1378,31 +1475,61 @@
                     syncCompleteDeleteList.put(pccId.ipAddress(), tunnelToBeDeletedList);
                     return;
                 }
+                DeviceId deviceId = getDevice(pccId);
+                if (deviceId == null) {
+                    log.error("Ingress deviceId not found");
+                    return;
+                }
+                annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType);
 
-                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();
+                td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
+                        0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
+                        annotations);
+                /*
+                 * 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;
             }
 
+            //delegated owner will update can be a master or non-master
+            if (lspObj.getDFlag()) {
+                annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType);
+                td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
+                        0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
+                        annotations);
+                tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
+            }
+
             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());
@@ -1410,12 +1537,15 @@
                 syncCompleteUpdateList.put(pccId.ipAddress(), tunnelToBeUpdateList);
                 return;
             }
+            removeOrUpdatetunnel(tunnel, pccId, lspObj, providerId, syncStatus, 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,
+                PcepSyncStatus syncStatus, 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 {
@@ -1424,7 +1554,21 @@
                 }
                 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);
         }
 
         /**
@@ -1578,4 +1722,83 @@
             pcepClientController.getClient(pccId).setLabelDbSyncStatus(IN_SYNC);
         }
     }
+
+    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;
+        }
+
+        //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;
+                }
+
+                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;
+                }
+            }
+
+            //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 2babb3a..4f6178a 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,11 +17,14 @@
 
 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.LspKey;
 import org.onosproject.pcep.controller.PccId;
 import org.onosproject.pcep.controller.PcepClient;
 import org.onosproject.pcep.controller.PcepSyncStatus;
@@ -45,6 +48,7 @@
     private PcepVersion pcepVersion;
     private PcepSyncStatus lspDbSyncStatus;
     private PcepSyncStatus labelDbSyncStatus;
+    private Map<LspKey, Boolean> lspDelegationInfo = new HashMap<>();
 
     /**
      * Initialize instance with specified parameters.
@@ -147,4 +151,14 @@
     @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);
+    }
 }
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 39d863b..769268b 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,8 +24,6 @@
 
 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;
@@ -75,16 +73,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, 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;
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 9d80daf..fe2c8b2 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,36 @@
 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 +61,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 +90,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 +176,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 +269,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 +314,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 +371,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, false, false));
+        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.
@@ -308,15 +431,127 @@
         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, false, false));
+        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 LSPDB sync where PCC reports less LSPs than known by PCE and PCE deletes at the end of DB sync.
      */
     @Test
@@ -355,8 +590,23 @@
         PcepMessageReader<PcepMessage> reader1 = PcepFactories.getGenericReader();
         PcepMessage message1 = reader1.readFrom(buffer1);
 
+        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).setCapability(new ClientCapability(true, true, true, false, false));
+        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(2, (short) 2), true);
+        masterShipService.setMaster(true);
         controller.processClientMessage(pccId, message1);
 
         /* create 2nd LSP */
@@ -494,8 +744,24 @@
         PcepMessageReader<PcepMessage> reader1 = PcepFactories.getGenericReader();
         PcepMessage message1 = reader1.readFrom(buffer1);
 
+        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).setCapability(new ClientCapability(true, true, true, false, false));
+        controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
+        PcepClientAdapter pc = new PcepClientAdapter();
+        pc.init(pccId, PcepVersion.PCEP_1);
+        masterShipService.setMaster(true);
+        controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(2, (short) 2), true);
+
         controller.processClientMessage(pccId, message1);
 
         /* create 2nd LSP */
@@ -604,6 +870,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()));
     }