diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/BasicPceccHandler.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/BasicPceccHandler.java
new file mode 100644
index 0000000..3ed670d
--- /dev/null
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/BasicPceccHandler.java
@@ -0,0 +1,318 @@
+/*
+ * 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.pce.pceservice;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.LinkedList;
+
+import org.onosproject.incubator.net.resource.label.DefaultLabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourceService;
+import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.pce.pcestore.api.PceStore;
+import org.onosproject.pce.pcestore.api.LspLocalLabelInfo;
+import org.onosproject.pce.pcestore.PceccTunnelInfo;
+import org.onosproject.pce.pcestore.DefaultLspLocalLabelInfo;
+import org.onosproject.net.Link;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * Basic PCECC handler.
+ * In Basic PCECC, after path computation will configure IN and OUT label to nodes.
+ * [X]OUT---link----IN[Y]OUT---link-----IN[Z] where X, Y and Z are nodes.
+ * For generating labels, will go thorough links in the path from Egress to Ingress.
+ * In each link, will take label from destination node local pool as IN label,
+ * and assign this label as OUT label to source node.
+ */
+public final class BasicPceccHandler {
+    private static final Logger log = LoggerFactory.getLogger(BasicPceccHandler.class);
+
+    private static final String LABEL_RESOURCE_SERVICE_NULL = "Label Resource Service cannot be null";
+    private static final String PCE_STORE_NULL = "PCE Store cannot be null";
+    private static BasicPceccHandler crHandlerInstance = null;
+    private LabelResourceService labelRsrcService;
+    private PceStore pceStore;
+
+    /**
+     * Initializes default values.
+     */
+    private BasicPceccHandler() {
+    }
+
+    /**
+     * Returns single instance of this class.
+     *
+     * @return this class single instance
+     */
+    public static BasicPceccHandler getInstance() {
+        if (crHandlerInstance == null) {
+            crHandlerInstance = new BasicPceccHandler();
+        }
+        return crHandlerInstance;
+    }
+
+    /**
+     * Initialization of label manager and pce store.
+     *
+     * @param labelRsrcService label resource service
+     * @param pceStore pce label store
+     */
+    public void initialize(LabelResourceService labelRsrcService, PceStore pceStore) {
+        this.labelRsrcService = labelRsrcService;
+        this.pceStore = pceStore;
+    }
+
+    /**
+     * Allocates labels from local resource pool and configure these (IN and OUT) labels into devices.
+     *
+     * @param tunnel tunnel between ingress to egress
+     * @return success or failure
+     */
+    public boolean allocateLabel(Tunnel tunnel) {
+        long applyNum = 1;
+        boolean isLastLabelToPush = false;
+        Collection<LabelResource> labelRscList;
+
+        checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+        checkNotNull(pceStore, PCE_STORE_NULL);
+
+        List<Link> linkList = tunnel.path().links();
+        if ((linkList != null) && (linkList.size() > 0)) {
+            // Sequence through reverse order to push local labels into devices
+            // Generation of labels from egress to ingress
+            for (ListIterator iterator = linkList.listIterator(linkList.size()); iterator.hasPrevious();) {
+                Link link = (Link) iterator.previous();
+                DeviceId dstDeviceId = link.dst().deviceId();
+                DeviceId srcDeviceId = link.src().deviceId();
+                labelRscList = labelRsrcService.applyFromDevicePool(dstDeviceId, applyNum);
+                if ((labelRscList != null) && (labelRscList.size() > 0)) {
+                    // Link label value is taken from destination device local pool.
+                    // [X]OUT---link----IN[Y]OUT---link-----IN[Z] where X, Y and Z are nodes.
+                    // Link label value is used as OUT and IN for both ends
+                    // (source and destination devices) of the link.
+                    // Currently only one label is allocated to a device (destination device).
+                    // So, no need to iterate through list
+                    Iterator<LabelResource> labelIterator = labelRscList.iterator();
+                    DefaultLabelResource defaultLabelResource = (DefaultLabelResource) labelIterator.next();
+                    LabelResourceId labelId = defaultLabelResource.labelResourceId();
+                    log.debug("Allocated local label: " + labelId.toString()
+                              + "to device: " + defaultLabelResource.deviceId().toString());
+                    PortNumber dstPort = link.dst().port();
+
+                    // Check whether this is last link label to push
+                    if (!iterator.hasPrevious()) {
+                       isLastLabelToPush = true;
+                    }
+
+                    // Push into destination device
+                    //TODO: uncomment below lines once installLocalLabelRule() method is ready
+                    // Destination device IN port is link.dst().port()
+                    //installLocalLabelRule(dstDeviceId, labelId, dstPort, tunnel.tunnelId(), isLastLabelToPush,
+                    //                      LabelType.IN, Objective.Operation.ADD);
+
+                    // Push into source device
+                    //TODO: uncomment below lines once installLocalLabelRule() method is ready
+                    // Source device OUT port will be link.dst().port(). Means its remote port used to send packet.
+                    //installLocalLabelRule(srcDeviceId, labelId, dstPort, tunnel.tunnelId(), isLastLabelToPush,
+                    //                      LabelType.OUT, Objective.Operation.ADD);
+
+                    // Add or update pcecc tunnel info in pce store.
+                    updatePceccTunnelInfoInStore(srcDeviceId, dstDeviceId, labelId, dstPort,
+                                                 tunnel, isLastLabelToPush);
+                } else {
+                    log.error("Unable to allocate label to device id {}.", dstDeviceId.toString());
+                    releaseLabel(tunnel);
+                    return false;
+                }
+            }
+        } else {
+           log.error("Tunnel {} is having empty links.", tunnel.toString());
+           return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Updates list of local labels of PCECC tunnel info in pce store.
+     *
+     * @param srcDeviceId source device in a link
+     * @param dstDeviceId destination device in a link
+     * @param labelId label id of a link
+     * @param dstPort destination device port number of a link
+     * @param tunnel tunnel
+     * @param isLastLabelToPush indicates this is the last label to push in Basic PCECC case
+     */
+    public void updatePceccTunnelInfoInStore(DeviceId srcDeviceId, DeviceId dstDeviceId, LabelResourceId labelId,
+                                                PortNumber dstPort, Tunnel tunnel, boolean isLastLabelToPush) {
+       // First try to retrieve device from store and update its label id if it is exists,
+       // otherwise add it
+       boolean dstDeviceUpdated = false;
+       boolean srcDeviceUpdated = false;
+
+       PceccTunnelInfo pceccTunnelInfo = pceStore.getTunnelInfo(tunnel.tunnelId());
+       List<LspLocalLabelInfo> lspLabelInfoList;
+       if (pceccTunnelInfo != null) {
+           lspLabelInfoList = pceccTunnelInfo.lspLocalLabelInfoList();
+           if ((lspLabelInfoList != null) && (lspLabelInfoList.size() > 0)) {
+               for (int i = 0; i < lspLabelInfoList.size(); ++i) {
+                   LspLocalLabelInfo lspLocalLabelInfo =
+                           (DefaultLspLocalLabelInfo) lspLabelInfoList.get(i);
+                   LspLocalLabelInfo.Builder lspLocalLabelInfoBuilder = null;
+                   if (dstDeviceId.equals(lspLocalLabelInfo.deviceId())) {
+                       lspLocalLabelInfoBuilder = DefaultLspLocalLabelInfo.builder(lspLocalLabelInfo);
+                       lspLocalLabelInfoBuilder.inLabelId(labelId);
+                       // Destination device IN port will be link destination port
+                       lspLocalLabelInfoBuilder.inPort(dstPort);
+                       dstDeviceUpdated = true;
+                   } else if (srcDeviceId.equals(lspLocalLabelInfo.deviceId())) {
+                       lspLocalLabelInfoBuilder = DefaultLspLocalLabelInfo.builder(lspLocalLabelInfo);
+                       lspLocalLabelInfoBuilder.outLabelId(labelId);
+                       // Source device OUT port will be link destination (remote) port
+                       lspLocalLabelInfoBuilder.outPort(dstPort);
+                       srcDeviceUpdated = true;
+                   }
+
+                   // Update
+                   if ((lspLocalLabelInfoBuilder != null) && (dstDeviceUpdated || srcDeviceUpdated)) {
+                       lspLabelInfoList.set(i, lspLocalLabelInfoBuilder.build());
+                   }
+               }
+           }
+       }
+
+       // If it is not found in store then add it to store
+       if (!dstDeviceUpdated || !srcDeviceUpdated) {
+           // If tunnel info itself not available then create new one, otherwise add node to list.
+           if (pceccTunnelInfo == null) {
+              pceccTunnelInfo = new PceccTunnelInfo();
+              lspLabelInfoList = new LinkedList<>();
+           } else {
+              lspLabelInfoList = pceccTunnelInfo.lspLocalLabelInfoList();
+              if (lspLabelInfoList == null) {
+                 lspLabelInfoList = new LinkedList<>();
+              }
+           }
+
+           if (!dstDeviceUpdated) {
+               LspLocalLabelInfo lspLocalLabelInfo = DefaultLspLocalLabelInfo.builder()
+                   .deviceId(dstDeviceId)
+                   .inLabelId(labelId)
+                   .outLabelId(null)
+                   .inPort(dstPort) // Destination device IN port will be link destination port
+                   .outPort(null)
+                   .build();
+               lspLabelInfoList.add(lspLocalLabelInfo);
+           }
+
+           if (!srcDeviceUpdated) {
+               LspLocalLabelInfo lspLocalLabelInfo = DefaultLspLocalLabelInfo.builder()
+                   .deviceId(srcDeviceId)
+                   .inLabelId(null)
+                   .outLabelId(labelId)
+                   .inPort(null)
+                   .outPort(dstPort) // Source device OUT port will be link destination (remote) port
+                   .build();
+               lspLabelInfoList.add(lspLocalLabelInfo);
+           }
+
+           pceccTunnelInfo.lspLocalLabelInfoList(lspLabelInfoList);
+           pceStore.addTunnelInfo(tunnel.tunnelId(), pceccTunnelInfo);
+       }
+    }
+
+    /**
+     * Deallocates unused labels to device pools.
+     *
+     * @param tunnel tunnel between ingress to egress
+     */
+    public void releaseLabel(Tunnel tunnel) {
+       boolean isLastLabelToPush = false;
+
+       checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+       checkNotNull(pceStore, PCE_STORE_NULL);
+
+       Multimap<DeviceId, LabelResource> release = ArrayListMultimap.create();
+       PceccTunnelInfo pceccTunnelInfo = pceStore.getTunnelInfo(tunnel.tunnelId());
+       if (pceccTunnelInfo != null) {
+           List<LspLocalLabelInfo> lspLocalLabelInfoList = pceccTunnelInfo.lspLocalLabelInfoList();
+           if ((lspLocalLabelInfoList != null) && (lspLocalLabelInfoList.size() > 0)) {
+               for (Iterator<LspLocalLabelInfo> iterator = lspLocalLabelInfoList.iterator(); iterator.hasNext();) {
+                   LspLocalLabelInfo lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
+                   DeviceId deviceId = lspLocalLabelInfo.deviceId();
+                   LabelResourceId inLabelId = lspLocalLabelInfo.inLabelId();
+                   LabelResourceId outLabelId = lspLocalLabelInfo.outLabelId();
+                   PortNumber inPort = lspLocalLabelInfo.inPort();
+                   PortNumber outPort = lspLocalLabelInfo.outPort();
+
+                   // Check whether this is last link label to push
+                   if (!iterator.hasNext()) {
+                      isLastLabelToPush = true;
+                   }
+
+                   // Push into device
+                   if ((inLabelId != null) && (inPort != null)) {
+                       //TODO: uncomment below lines once installLocalLabelRule() method is ready
+                       //installLocalLabelRule(deviceId, inLabelId, inPort, tunnelId, isLastLabelToPush,
+                       //                      LabelType.IN, Objective.Operation.REMOVE);
+                   }
+
+                   if ((outLabelId != null) && (outPort != null)) {
+                       //TODO: uncomment below lines once installLocalLabelRule() method is ready
+                       //installLocalLabelRule(deviceId, outLabelId, outPort, tunnelId, isLastLabelToPush,
+                       //                      LabelType.OUT, Objective.Operation.REMOVE);
+                   }
+
+                   // List is stored from egress to ingress. So, using IN label id to release.
+                   // Only one local label is assigned to device (destination node)
+                   // and that is used as OUT label for source node.
+                   // No need to release label for last node in the list from pool because label was not allocated to
+                   // ingress node (source node).
+                   if ((iterator.hasNext()) && (inLabelId != null)) {
+                       LabelResource labelRsc = new DefaultLabelResource(deviceId, inLabelId);
+                       release.put(deviceId, labelRsc);
+                   }
+               }
+           }
+
+           // Release from label pool
+           if (!release.isEmpty()) {
+              labelRsrcService.releaseToDevicePool(release);
+           }
+
+           // Remove tunnel info only if tunnel consumer id is not saved.
+           // If tunnel consumer id is saved, this tunnel info will be removed during releasing bandwidth.
+           if (pceccTunnelInfo.tunnelConsumerId() == null) {
+               pceStore.removeTunnelInfo(tunnel.tunnelId());
+           }
+       } else {
+           log.error("Unable to find PCECC tunnel info in store for a tunnel {}.", tunnel.toString());
+       }
+   }
+}
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/LabelType.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/LabelType.java
new file mode 100644
index 0000000..78e57f0
--- /dev/null
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/LabelType.java
@@ -0,0 +1,52 @@
+/*
+ * 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.pce.pceservice;
+
+/**
+ * Describes about Label type.
+ */
+public enum LabelType {
+    /**
+     * Signifies in label id of a device.
+     */
+    OUT_LABEL(0),
+
+    /**
+     * Signifies out label id of a device.
+     */
+    IN_LABEL(1);
+
+    int value;
+
+    /**
+     * Assign val with the value as the Label type.
+     *
+     * @param val Label type
+     */
+    LabelType(int val) {
+        value = val;
+    }
+
+    /**
+     * Returns value of Label type.
+     *
+     * @return label type
+     */
+    public byte type() {
+        return (byte) value;
+    }
+}
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceccSrTeBeHandler.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceccSrTeBeHandler.java
new file mode 100644
index 0000000..2a10dcf
--- /dev/null
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceccSrTeBeHandler.java
@@ -0,0 +1,389 @@
+/*
+ * 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.pce.pceservice;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+import org.onosproject.incubator.net.resource.label.DefaultLabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceService;
+import org.onosproject.incubator.net.tunnel.DefaultLabelStack;
+import org.onosproject.incubator.net.tunnel.LabelStack;
+import org.onosproject.net.DeviceId;
+import org.onosproject.pce.pcestore.api.PceStore;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * PCE SR-BE and SR-TE functionality.
+ * SR-BE: Each node (PCC) is allocated a node-SID (label) by the PCECC. The PCECC sends PCLabelUpd to
+ * update the label map of each node to all the nodes in the domain.
+ * SR-TE: apart from node-SID, Adj-SID is used where each adjacency is allocated an Adj-SID (label) by the PCECC.
+ * The PCECC sends PCLabelUpd to update the label map of each Adj to the corresponding nodes in the domain.
+ */
+public final class PceccSrTeBeHandler {
+    private static final Logger log = LoggerFactory.getLogger(PceccSrTeBeHandler.class);
+
+    private static final String LABEL_RESOURCE_ADMIN_SERVICE_NULL = "Label Resource Admin Service cannot be null";
+    private static final String LABEL_RESOURCE_SERVICE_NULL = "Label Resource Service cannot be null";
+    private static final String PCE_STORE_NULL = "PCE Store cannot be null";
+    private static final String DEVICE_SERVICE_NULL = "Device Service cannot be null";
+    private static final String DEVICE_ID_NULL = "Device-Id cannot be null";
+    private static final String LSR_ID_NULL = "LSR-Id cannot be null";
+    private static final String DEVICE_ID_LSR_ID_MAP_NULL = "Device-Id and LSR-Id map cannot be null";
+    private static final String LINK_NULL = "Link cannot be null";
+    private static final String PATH_NULL = "Path cannot be null";
+    private static final String LSR_ID = "lsrId";
+    private static final int PREFIX_LENGTH = 32;
+    private static PceccSrTeBeHandler srTeHandlerInstance = null;
+    private LabelResourceAdminService labelRsrcAdminService;
+    private LabelResourceService labelRsrcService;
+    private PceStore pceStore;
+
+    /**
+     * Initializes default values.
+     */
+    private PceccSrTeBeHandler() {
+    }
+
+    /**
+     * Returns single instance of this class.
+     *
+     * @return this class single instance
+     */
+    public static PceccSrTeBeHandler getInstance() {
+        if (srTeHandlerInstance == null) {
+            srTeHandlerInstance = new PceccSrTeBeHandler();
+        }
+        return srTeHandlerInstance;
+    }
+
+    /**
+     * Initialization of label manager interfaces and pce store.
+     *
+     * @param labelRsrcAdminService label resource admin service
+     * @param labelRsrcService label resource service
+     * @param pceStore PCE label store
+     */
+    public void initialize(LabelResourceAdminService labelRsrcAdminService,
+                           LabelResourceService labelRsrcService, PceStore pceStore) {
+        this.labelRsrcAdminService = labelRsrcAdminService;
+        this.labelRsrcService = labelRsrcService;
+        this.pceStore = pceStore;
+    }
+
+    /**
+     * Reserves the global label pool.
+     *
+     * @param beginLabel minimum value of global label space
+     * @param endLabel maximum value of global label space
+     * @return success or failure
+     */
+    public boolean reserveGlobalPool(long beginLabel, long endLabel) {
+        checkNotNull(labelRsrcAdminService, LABEL_RESOURCE_ADMIN_SERVICE_NULL);
+        return labelRsrcAdminService.createGlobalPool(LabelResourceId.labelResourceId(beginLabel),
+                                                      LabelResourceId.labelResourceId(endLabel));
+    }
+
+    /**
+     * Allocates node label from global node label pool to specific device.
+     * Configure this device with labels and lsrid mapping of all other devices and vice versa.
+     *
+     * @param specificDeviceId node label needs to be allocated to specific device
+     * @param specificLsrId lsrid of specific device
+     * @param deviceIdLsrIdMap deviceid and lsrid mapping
+     * @return success or failure
+     */
+    public boolean allocateNodeLabel(DeviceId specificDeviceId, String specificLsrId,
+                                     Map<DeviceId, String> deviceIdLsrIdMap) {
+        long applyNum = 1; // For each node only one node label
+        LabelResourceId specificLabelId = null;
+
+        checkNotNull(specificDeviceId, DEVICE_ID_NULL);
+        checkNotNull(specificLsrId, LSR_ID_NULL);
+        checkNotNull(deviceIdLsrIdMap, DEVICE_ID_LSR_ID_MAP_NULL);
+        checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+        checkNotNull(pceStore, PCE_STORE_NULL);
+
+        // The specificDeviceId is the new device and is not there in the deviceIdLsrIdMap.
+        // So, first generate its label and configure label and its lsr-id to it.
+        Collection<LabelResource> result = labelRsrcService.applyFromGlobalPool(applyNum);
+        if (result.size() > 0) {
+           // Only one element (label-id) to retrieve
+           Iterator<LabelResource> iterator = result.iterator();
+           DefaultLabelResource defaultLabelResource = (DefaultLabelResource) iterator.next();
+           specificLabelId = defaultLabelResource.labelResourceId();
+           if (specificLabelId == null) {
+              log.error("Unable to retrieve global node label for a device id {}.", specificDeviceId.toString());
+              return false;
+           }
+        } else {
+           log.error("Unable to allocate global node label for a device id {}.", specificDeviceId.toString());
+           return false;
+        }
+
+        pceStore.addGlobalNodeLabel(specificDeviceId, specificLabelId);
+        //TODO: uncomment below line once advertiseNodeLabelRule() is ready
+        // Push its label information into specificDeviceId
+        //advertiseNodeLabelRule(specificDeviceId, specificLabelId,
+        //                       IpPrefix.valueOf(IpAddress.valueOf(specificLsrId), PREFIX_LENGTH),
+
+        // Configure (node-label, lsr-id) mapping of each devices in list to specific device and vice versa.
+        for (Map.Entry element:deviceIdLsrIdMap.entrySet()) {
+           DeviceId otherDevId = (DeviceId) element.getKey();
+           String otherLsrId = (String) element.getValue();
+           if (otherLsrId == null) {
+               log.error("The lsr-id of device id {} is null.", otherDevId.toString());
+               releaseNodeLabel(specificDeviceId, specificLsrId, deviceIdLsrIdMap);
+               return false;
+           }
+
+           // Label for other device in list should be already allocated.
+           LabelResourceId otherLabelId = pceStore.getGlobalNodeLabel(otherDevId);
+           if (otherLabelId == null) {
+              log.error("Unable to find global node label in store for a device id {}.", otherDevId.toString());
+              releaseNodeLabel(specificDeviceId, specificLsrId, deviceIdLsrIdMap);
+              return false;
+           }
+
+           // Push to device
+           // TODO: uncomment below line once advertiseNodeLabelRule() is ready
+           // Push label information of specificDeviceId to otherDevId in list and vice versa.
+           //advertiseNodeLabelRule(otherDevId, specificLabelId, IpPrefix.valueOf(IpAddress.valueOf(specificLsrId),
+           //                       PREFIX_LENGTH), Objective.Operation.ADD);
+           //advertiseNodeLabelRule(specificDeviceId, otherLabelId, IpPrefix.valueOf(IpAddress.valueOf(otherLsrId),
+           //                       PREFIX_LENGTH), Objective.Operation.ADD);
+        }
+
+        return true;
+    }
+
+    /**
+     * Releases assigned node label of specific device from global node label pool and pce store.
+     * and remove configured this node label from all other devices.
+     *
+     * @param specificDeviceId node label needs to be released for specific device
+     * @param specificLsrId lsrid of specific device
+     * @param deviceIdLsrIdMap deviceid and lsrid mapping
+     * @return success or failure
+     */
+    public boolean releaseNodeLabel(DeviceId specificDeviceId, String specificLsrId,
+                                    Map<DeviceId, String> deviceIdLsrIdMap) {
+        checkNotNull(specificDeviceId, DEVICE_ID_NULL);
+        checkNotNull(specificLsrId, LSR_ID_NULL);
+        checkNotNull(deviceIdLsrIdMap, DEVICE_ID_LSR_ID_MAP_NULL);
+        checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+        checkNotNull(pceStore, PCE_STORE_NULL);
+        boolean retValue = true;
+
+        // Release node label entry of this specific device from all other devices
+        // Retrieve node label of this specific device from store
+        LabelResourceId labelId = pceStore.getGlobalNodeLabel(specificDeviceId);
+        if (labelId == null) {
+           log.error("Unable to retrieve label of a device id {} from store.", specificDeviceId.toString());
+           return false;
+        }
+
+        // Go through all devices in the map and remove label entry
+        for (Map.Entry element:deviceIdLsrIdMap.entrySet()) {
+           DeviceId otherDevId = (DeviceId) element.getKey();
+
+           // Remove this specific device label information from all other nodes except
+           // this specific node where connection already lost.
+           if (!specificDeviceId.equals(otherDevId)) {
+              //TODO: uncomment below lines once advertiseNodeLabelRule() is ready
+              //advertiseNodeLabelRule(otherDevId, labelId, IpPrefix.valueOf(IpAddress.valueOf(specificLsrId),
+              //                       PREFIX_LENGTH), Objective.Operation.REMOVE);
+           }
+        }
+
+        // Release from label manager
+        Set<LabelResourceId> release = new HashSet<>();
+        release.add(labelId);
+        if (!labelRsrcService.releaseToGlobalPool(release)) {
+            log.error("Unable to release label id {} from label manager.", labelId.toString());
+            retValue = false;
+        }
+
+        // Remove from store
+        if (!pceStore.removeGlobalNodeLabel(specificDeviceId)) {
+            log.error("Unable to remove global node label id {} from store.", labelId.toString());
+            retValue = false;
+        }
+
+        return retValue;
+    }
+
+    /**
+     * Allocates adjacency label to a link from local resource pool by a specific device id.
+     *
+     * @param link between devices
+     * @return success or failure
+     */
+    public boolean allocateAdjacencyLabel(Link link) {
+        long applyNum = 1; // Single label to each link.
+        DeviceId srcDeviceId = link.src().deviceId();
+        Collection<LabelResource> labelList;
+
+        checkNotNull(link, LINK_NULL);
+        checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+        checkNotNull(pceStore, PCE_STORE_NULL);
+
+        // Allocate adjacency label to a link from label manager.
+        // Take label from source device pool to allocate.
+        labelList = labelRsrcService.applyFromDevicePool(srcDeviceId, applyNum);
+        if (labelList.size() <= 0) {
+           log.error("Unable to allocate label to a device id {}.", srcDeviceId.toString());
+           return false;
+        }
+
+        // Currently only one label to a device. So, no need to iterate through list
+        Iterator<LabelResource> iterator = labelList.iterator();
+        DefaultLabelResource defaultLabelResource = (DefaultLabelResource) iterator.next();
+        LabelResourceId labelId = defaultLabelResource.labelResourceId();
+        if (labelId == null) {
+           log.error("Unable to allocate label to a device id {}.", srcDeviceId.toString());
+           return false;
+        }
+        log.debug("Allocated adjacency label {} to a link {}.", labelId.toString(),
+                  link.toString());
+
+        // Push adjacency label to device
+        //TODO: uncomment below line once installAdjLabelRule() method is ready
+        //installAdjLabelRule(srcDeviceId, labelId, link.src().port(), link.dst().port(), Objective.Operation.ADD);
+
+        // Save in store
+        pceStore.addAdjLabel(link, labelId);
+        return true;
+    }
+
+   /**
+     * Releases unused adjacency labels from device pools.
+     *
+     * @param link between devices
+     * @return success or failure
+     */
+    public boolean releaseAdjacencyLabel(Link link) {
+       checkNotNull(link, LINK_NULL);
+       checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+       checkNotNull(pceStore, PCE_STORE_NULL);
+       boolean retValue = true;
+
+       // Retrieve link label from store
+       LabelResourceId labelId = pceStore.getAdjLabel(link);
+       if (labelId == null) {
+          log.error("Unabel to retrieve label for a link {} from store.", link.toString());
+          return false;
+       }
+
+       // Device
+       DeviceId srcDeviceId = link.src().deviceId();
+
+       // Release adjacency label from device
+       //TODO: uncomment below line once installAdjLabelRule() method is ready
+       //installAdjLabelRule(srcDeviceId, labelId, link.src().port(), link.dst().port(), Objective.Operation.REMOVE);
+
+       // Release link label from label manager
+       Multimap<DeviceId, LabelResource> release = ArrayListMultimap.create();
+       DefaultLabelResource defaultLabelResource = new DefaultLabelResource(srcDeviceId, labelId);
+       release.put(srcDeviceId, defaultLabelResource);
+       if (!labelRsrcService.releaseToDevicePool(release)) {
+          log.error("Unable to release label id {} from label manager.", labelId.toString());
+          retValue = false;
+       }
+
+       // Remove adjacency label from store
+       if (!pceStore.removeAdjLabel(link)) {
+          log.error("Unable to remove adjacency label id {} from store.", labelId.toString());
+          retValue = false;
+       }
+       return retValue;
+    }
+
+    /**
+     * Computes label stack for a path.
+     *
+     * @param path lsp path
+     * @return label stack
+     */
+    public LabelStack computeLabelStack(Path path) {
+        checkNotNull(path, PATH_NULL);
+        // Label stack is linked list to make labels in order.
+        List<LabelResourceId> labelStack = new LinkedList<>();
+        List<Link> linkList = path.links();
+        if ((linkList != null) && (linkList.size() > 0)) {
+            // Path: [x] ---- [y] ---- [z]
+            // For other than last link, add only source[x] device label.
+            // For the last link, add both source[y] and destination[z] device labels.
+            // For all links add adjacency label
+            Link link = null;
+            LabelResourceId nodeLabelId = null;
+            LabelResourceId adjLabelId = null;
+            DeviceId deviceId = null;
+            for (Iterator<Link> iterator = linkList.iterator(); iterator.hasNext();) {
+                link = (Link) iterator.next();
+                // Add source device label now
+                deviceId = link.src().deviceId();
+                nodeLabelId = pceStore.getGlobalNodeLabel(deviceId);
+                if (nodeLabelId == null) {
+                   log.error("Unable to find node label for a device id {} in store.", deviceId.toString());
+                   return null;
+                }
+                labelStack.add(nodeLabelId);
+
+                // Add adjacency label for this link
+                adjLabelId = pceStore.getAdjLabel(link);
+                if (adjLabelId == null) {
+                   log.error("Adjacency label id is null for a link {}.", link.toString());
+                   return null;
+                }
+                labelStack.add(adjLabelId);
+            }
+
+            // This is the last link in path
+            // Add destination device label now.
+            if (link != null) {
+               deviceId = link.dst().deviceId();
+               nodeLabelId = pceStore.getGlobalNodeLabel(deviceId);
+               if (nodeLabelId == null) {
+                  log.error("Unable to find node label for a device id {} in store.", deviceId.toString());
+                  return null;
+               }
+               labelStack.add(nodeLabelId);
+            }
+        } else {
+            log.debug("Empty link in path.");
+            return null;
+        }
+        return new DefaultLabelStack(labelStack);
+    }
+}
