diff --git a/providers/bgpcep/flow/src/main/java/org/onosproject/provider/bgpcep/flow/impl/BgpcepFlowRuleProvider.java b/providers/bgpcep/flow/src/main/java/org/onosproject/provider/bgpcep/flow/impl/BgpcepFlowRuleProvider.java
index 3afbec4..6d0ad11 100644
--- a/providers/bgpcep/flow/src/main/java/org/onosproject/provider/bgpcep/flow/impl/BgpcepFlowRuleProvider.java
+++ b/providers/bgpcep/flow/src/main/java/org/onosproject/provider/bgpcep/flow/impl/BgpcepFlowRuleProvider.java
@@ -15,25 +15,62 @@
  */
 package org.onosproject.provider.bgpcep.flow.impl;
 
+import java.util.LinkedList;
+import java.util.List;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
 import org.onosproject.bgp.controller.BgpController;
 import org.onosproject.cfg.ComponentConfigService;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
+import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.tunnel.TunnelService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.FlowRuleBatchOperation;
 import org.onosproject.net.flow.FlowRuleProvider;
 import org.onosproject.net.flow.FlowRuleProviderRegistry;
 import org.onosproject.net.flow.FlowRuleProviderService;
 import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flowobjective.Objective;
 import org.onosproject.net.provider.AbstractProvider;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.net.resource.ResourceService;
 import org.onosproject.pcep.controller.PcepClient;
 import org.onosproject.pcep.controller.PcepClientController;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepEroObject;
+import org.onosproject.pcepio.protocol.PcepFecObjectIPv4;
+import org.onosproject.pcepio.protocol.PcepFecObjectIPv4Adjacency;
+import org.onosproject.pcepio.protocol.PcepLabelObject;
+import org.onosproject.pcepio.protocol.PcepLabelUpdate;
+import org.onosproject.pcepio.protocol.PcepLabelUpdateMsg;
+import org.onosproject.pcepio.protocol.PcepLspObject;
+import org.onosproject.pcepio.protocol.PcepMsgPath;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.onosproject.pcepio.protocol.PcepUpdateMsg;
+import org.onosproject.pcepio.protocol.PcepUpdateRequest;
+import org.onosproject.pcepio.types.IPv4SubObject;
+import org.onosproject.pcepio.types.NexthopIPv4addressTlv;
+import org.onosproject.pcepio.types.PcepLabelDownload;
+import org.onosproject.pcepio.types.PcepLabelMap;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
+import org.onosproject.provider.pcep.tunnel.impl.SrpIdGenerators;
+import org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 
@@ -63,7 +100,15 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ResourceService resourceService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TunnelService tunnelService;
+
     private FlowRuleProviderService providerService;
+    private PcepLabelObject labelObj;
+    public static final int OUT_LABEL_TYPE = 0;
+    public static final int IN_LABEL_TYPE = 1;
+    public static final long IDENTIFIER_SET = 0x100000000L;
+    public static final long SET = 0xFFFFFFFFL;
 
     /**
      * Creates a BgpFlow host provider.
@@ -120,6 +165,286 @@
                     });
     }
 
+    /**
+     * Returns PCEP client.
+     *
+     * @return PCEP client
+     */
+    private PcepClient getPcepClient(DeviceId deviceId) {
+        PcepClient pcc;
+        //TODO: commented code has dependency
+     /*   Set<TeRouterId> lrsIds = resourceService.getAvailableResourceValues(Resources
+                .discrete(deviceId()).id(), TeRouterId.class);
+
+        lrsIds.forEach(lsrId ->
+        {
+            if (pcepController.getClient(PccId.pccId(lsrId)) != null) {
+                pcc = pcepController.getClient(PccId.pccId(lsrId));
+                return pcc
+            }
+        });*/
+        return null;
+    }
+
+    //Pushes node labels to the specified device.
+    private void pushGlobalNodeLabel(DeviceId deviceId, LabelResourceId labelId,
+            IpPrefix ipPrefix, Objective.Operation type) throws PcepParseException {
+        PcepClient pc = getPcepClient(deviceId);
+        if (pc == null) {
+            log.error("PCEP client not found");
+            return;
+        }
+
+        LinkedList<PcepLabelUpdate> labelUpdateList = new LinkedList<>();
+
+        PcepFecObjectIPv4 fecObject = pc.factory().buildFecObjectIpv4()
+                                      .setNodeID(ipPrefix.address().getIp4Address().toInt())
+                                      .build();
+
+        PcepSrpObject srpObj = getSrpObject(pc, type);
+
+        //Global NODE-SID as label object
+        PcepLabelObject labelObject = pc.factory().buildLabelObject()
+                                      .setLabel((int) labelId.labelId())
+                                      .build();
+
+        PcepLabelMap labelMap = new PcepLabelMap();
+        labelMap.setFecObject(fecObject);
+        labelMap.setLabelObject(labelObject);
+        labelMap.setSrpObject(srpObj);
+
+        labelUpdateList.add(pc.factory().buildPcepLabelUpdateObject()
+                            .setLabelMap(labelMap)
+                            .build());
+
+        PcepLabelUpdateMsg labelMsg = pc.factory().buildPcepLabelUpdateMsg()
+                                      .setPcLabelUpdateList(labelUpdateList)
+                                      .build();
+
+        pc.sendMessage(labelMsg);
+    }
+
+    private PcepSrpObject getSrpObject(PcepClient pc, Objective.Operation type) throws PcepParseException {
+        PcepSrpObject srpObj;
+        if (type.equals(Objective.Operation.ADD)) {
+            srpObj = pc.factory().buildSrpObject()
+                    .setRFlag(false)
+                    .setSrpID(SrpIdGenerators.create())
+                    .build();
+        } else {
+            //To cleanup labels, R bit is set
+            srpObj = pc.factory().buildSrpObject()
+                    .setRFlag(true)
+                    .setSrpID(SrpIdGenerators.create())
+                    .build();
+        }
+        return srpObj;
+    }
+
+    //Pushes adjacency labels to the specified device.
+    private void pushAdjacencyLabel(DeviceId deviceId, LabelResourceId labelId,
+            PortNumber srcPortNum, PortNumber dstPortNum, Objective.Operation type) throws PcepParseException {
+        PcepClient pc = getPcepClient(deviceId);
+        if (pc == null) {
+            log.error("PCEP client not found");
+            return;
+        }
+
+        LinkedList<PcepLabelUpdate> labelUpdateList = new LinkedList<>();
+
+        long srcPortNo = srcPortNum.toLong();
+        long dstPortNo = dstPortNum.toLong();
+        srcPortNo = ((srcPortNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? srcPortNo & SET : srcPortNo;
+        dstPortNo = ((dstPortNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? dstPortNo & SET : dstPortNo;
+
+        PcepFecObjectIPv4Adjacency fecAdjObject = pc.factory().buildFecIpv4Adjacency()
+                                                  .seRemoteIPv4Address((int) dstPortNo)
+                                                  .seLocalIPv4Address((int) srcPortNo)
+                                                  .build();
+
+        PcepSrpObject srpObj = getSrpObject(pc, type);
+
+        //Adjacency label object
+        PcepLabelObject labelObject = pc.factory().buildLabelObject()
+                                      .setLabel((int) labelId.labelId())
+                                      .build();
+
+        PcepLabelMap labelMap = new PcepLabelMap();
+        labelMap.setFecObject(fecAdjObject);
+        labelMap.setLabelObject(labelObject);
+        labelMap.setSrpObject(srpObj);
+
+        labelUpdateList.add(pc.factory().buildPcepLabelUpdateObject()
+                            .setLabelMap(labelMap)
+                            .build());
+
+        PcepLabelUpdateMsg labelMsg = pc.factory().buildPcepLabelUpdateMsg()
+                                      .setPcLabelUpdateList(labelUpdateList)
+                                      .build();
+
+        pc.sendMessage(labelMsg);
+    }
+
+    //Pushes local labels to the device which is specific to path [CR-case].
+    private void pushLocalLabels(DeviceId deviceId, LabelResourceId labelId,
+            PortNumber portNum, TunnelId tunnelId,
+            Boolean isBos, Long labelType, Objective.Operation type) throws PcepParseException {
+
+        PcepClient pc = getPcepClient(deviceId);
+        if (pc == null) {
+            log.error("PCEP client not found");
+            return;
+        }
+
+        PcepLspObject lspObj;
+        LinkedList<PcepLabelUpdate> labelUpdateList = new LinkedList<>();
+        LinkedList<PcepLabelObject> labelObjects = new LinkedList<>();
+        PcepSrpObject srpObj;
+        PcepLabelDownload labelDownload = new PcepLabelDownload();
+        LinkedList<PcepValueType> optionalTlv = new LinkedList<>();
+
+        long portNo = portNum.toLong();
+        portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
+
+        optionalTlv.add(NexthopIPv4addressTlv.of((int) portNo));
+
+        Tunnel tunnel = tunnelService.queryTunnel(tunnelId);
+
+        PcepLabelObject labelObj = pc.factory().buildLabelObject()
+                                   .setOFlag(labelType == OUT_LABEL_TYPE ? true : false)
+                                   .setOptionalTlv(optionalTlv)
+                                   .setLabel((int) labelId.labelId())
+                                   .build();
+
+        /**
+         * Check whether transit node or not. For transit node, label update message should include IN and OUT labels.
+         * Hence store IN label object and next when out label comes add IN and OUT label objects and encode label
+         * update message and send to specified client.
+         */
+        if (!deviceId.equals(tunnel.path().src().deviceId()) && !deviceId.equals(tunnel.path().dst().deviceId())) {
+            //Device is transit node
+            if (labelType == IN_LABEL_TYPE) {
+                //Store label object having IN label value
+                this.labelObj = labelObj;
+                return;
+            }
+            //Add IN label object
+            labelObjects.add(this.labelObj);
+        }
+
+        //Add OUT label object in case of transit node
+        labelObjects.add(labelObj);
+
+        srpObj = getSrpObject(pc, type);
+
+        String lspId = tunnel.annotations().value(PcepAnnotationKeys.PLSP_ID);
+        String plspId = tunnel.annotations().value(PcepAnnotationKeys.LOCAL_LSP_ID);
+        String tunnelIdentifier = tunnel.annotations().value(PcepAnnotationKeys.PCC_TUNNEL_ID);
+
+        LinkedList<PcepValueType> tlvs = new LinkedList<>();
+        StatefulIPv4LspIdentifiersTlv lspIdTlv = new StatefulIPv4LspIdentifiersTlv(((IpTunnelEndPoint) tunnel.src())
+                .ip().getIp4Address().toInt(), Short.valueOf(lspId), Short.valueOf(tunnelIdentifier), 0,
+                ((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt());
+        tlvs.add(lspIdTlv);
+
+        lspObj = pc.factory().buildLspObject()
+                .setRFlag(false)
+                .setAFlag(true)
+                .setDFlag(true)
+                .setPlspId(Integer.valueOf(plspId))
+                .setOptionalTlv(tlvs)
+                .build();
+
+        labelDownload.setLabelList(labelObjects);
+        labelDownload.setLspObject(lspObj);
+        labelDownload.setSrpObject(srpObj);
+
+        labelUpdateList.add(pc.factory().buildPcepLabelUpdateObject()
+                            .setLabelDownload(labelDownload)
+                            .build());
+
+        PcepLabelUpdateMsg labelMsg = pc.factory().buildPcepLabelUpdateMsg()
+                                      .setPcLabelUpdateList(labelUpdateList)
+                                      .build();
+
+        pc.sendMessage(labelMsg);
+
+        //If isBos is true, label download is done along the LSP, send PCEP update message.
+        if (isBos) {
+            sendPcepUpdateMsg(pc, lspObj, tunnel);
+        }
+    }
+
+    //Sends PCEP update message.
+    private void sendPcepUpdateMsg(PcepClient pc, PcepLspObject lspObj, Tunnel tunnel) throws PcepParseException {
+        LinkedList<PcepUpdateRequest> updateRequestList = new LinkedList<>();
+        LinkedList<PcepValueType> subObjects = createEroSubObj(tunnel.path());
+
+        if (subObjects == null) {
+            log.error("ERO subjects not present");
+            return;
+        }
+
+        PcepSrpObject srpObj = pc.factory().buildSrpObject()
+                               .setRFlag(false)
+                               .setSrpID(SrpIdGenerators.create())
+                               .build();
+
+        PcepEroObject eroObj = pc.factory().buildEroObject()
+                              .setSubObjects(subObjects)
+                              .build();
+
+        PcepMsgPath msgPath = pc.factory().buildPcepMsgPath()
+                              .setEroObject(eroObj)
+                              .build();
+
+        PcepUpdateRequest updateReq = pc.factory().buildPcepUpdateRequest()
+                                     .setSrpObject(srpObj)
+                                     .setMsgPath(msgPath)
+                                     .setLspObject(lspObj)
+                                     .build();
+
+        updateRequestList.add(updateReq);
+
+        //TODO: P = 1 is it P flag in PCEP obj header
+        PcepUpdateMsg updateMsg = pc.factory().buildUpdateMsg()
+                                  .setUpdateRequestList(updateRequestList)
+                                  .build();
+
+        pc.sendMessage(updateMsg);
+    }
+
+    private LinkedList<PcepValueType> createEroSubObj(Path path) {
+        LinkedList<PcepValueType> subObjects = new LinkedList<>();
+        List<Link> links = path.links();
+        ConnectPoint source = null;
+        ConnectPoint destination = null;
+        IpAddress ipDstAddress = null;
+        IpAddress ipSrcAddress = null;
+        PcepValueType subObj = null;
+        long portNo;
+
+        for (Link link : links) {
+            source = link.src();
+            if (!(source.equals(destination))) {
+                //set IPv4SubObject for ERO object
+                portNo = source.port().toLong();
+                portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
+                ipSrcAddress = Ip4Address.valueOf((int) portNo);
+                subObj = new IPv4SubObject(ipSrcAddress.getIp4Address().toInt());
+                subObjects.add(subObj);
+            }
+
+            destination = link.dst();
+            portNo = destination.port().toLong();
+            portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
+            ipDstAddress = Ip4Address.valueOf((int) portNo);
+            subObj = new IPv4SubObject(ipDstAddress.getIp4Address().toInt());
+            subObjects.add(subObj);
+        }
+        return subObjects;
+    }
+
     @Override
     public void removeFlowRule(FlowRule... flowRules) {
         for (FlowRule flowRule : flowRules) {
