diff --git a/app/src/main/java/org/opencord/olttopology/impl/OltTopology.java b/app/src/main/java/org/opencord/olttopology/impl/OltTopology.java
new file mode 100644
index 0000000..a0bf497
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/impl/OltTopology.java
@@ -0,0 +1,770 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.opencord.olttopology.impl;
+
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.LLDP;
+import org.onlab.packet.LLDPTLV;
+import org.onlab.packet.MacAddress;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.codec.CodecService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.opencord.olttopology.OltNeighborInfo;
+import org.opencord.olttopology.OltTopologyInformationService;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
+
+import static org.onlab.util.Tools.get;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_CHASSIS_ID;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_CHASSIS_ID_DEFAULT;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_DEST_MAC_ADDRESS;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_DEST_MAC_ADDRESS_DEFAULT;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_TTL_IN_SECS;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_TTL_IN_SECS_DEFAULT;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_LLDP_SEND_PERIODICITY;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.LLDP_SEND_PERIODICITY_STR;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Application to keep track of the topology of OLT devices.
+ */
+@Component(immediate = true,
+        property = {
+                DEFAULT_DEST_MAC_ADDRESS + ":String=" + DEFAULT_DEST_MAC_ADDRESS_DEFAULT,
+                DEFAULT_TTL_IN_SECS + ":Integer=" + DEFAULT_TTL_IN_SECS_DEFAULT,
+                DEFAULT_CHASSIS_ID + ":Integer=" + DEFAULT_CHASSIS_ID_DEFAULT,
+                LLDP_SEND_PERIODICITY_STR + ":Integer=" + DEFAULT_LLDP_SEND_PERIODICITY
+        }
+)
+public class OltTopology implements OltTopologyInformationService {
+    // Subtype value for IPv4 as per the LLDP specs
+    public static final byte IP_ADDR_SUB_TYPE = 0x1;
+    // 5 below is address subtype + IP4 address len
+    public static final byte IP_ADDR_STRING_LEN = 0x5;
+    // Value of interface sub type as per the LLDP specs
+    public static final byte INTERFACE_SUB_TYPE = 0x1;
+    // Value of interface number set in the management address
+    // field of LLDP packets being sent out
+    public static final int INTERFACE_NUM = 0;
+    // Value of the OID set in the management address field of
+    // LLDP packets being sent out
+    public static final byte OID_STRING = 0x0;
+    // Value of SystemName TLV as per the LLDP specs
+    public static final byte SYSTEMNAME_TLV_TYPE = 0x5;
+    // Value of Management Address TLV as per the LLDP specs
+    public static final byte MANAGEMENT_ADDR_TLV_TYPE = 0x8;
+    // Value of Port TLV sub type as per the LLDP specs
+    public static final byte PORT_TLV_SUB_TYPE = 5;
+    private static final String APP_NAME = "org.opencord.olttopology";
+    // Name for the consistent map where the neighbor information is stored
+    private static final String NEIGHBORS = "olt-neighbors";
+    private final Logger log = getLogger(getClass());
+    // deviceListener to be able to receive events about the OLT devices
+    private final DeviceListener deviceListener = new InternalDeviceListener();
+    // Service to execute periodic sending of LLDP packets
+    private final ScheduledExecutorService scheduledExecutorService =
+            Executors.newSingleThreadScheduledExecutor();
+    // our application-specific event handler for processing LLDP messages
+    // received from the OLT devices
+    private final ReactivePacketProcessor processor = new ReactivePacketProcessor();
+    // Map for storing information about the OLTs, is map of OLT deviceId to
+    // uplink port of the OLT
+    private final Map<DeviceId, Port> oltPortMap = new ConcurrentHashMap<>();
+    // cfg variable to set the parameters dynamically.
+    protected String destMacAddress = DEFAULT_DEST_MAC_ADDRESS_DEFAULT;
+    // References to the various services that this app uses
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected MastershipService mastershipService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected DeviceService deviceService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected CoreService coreService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ComponentConfigService componentConfigService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected PacketService packetService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected StorageService storageService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected CodecService codecService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected SadisService sadisService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected FlowObjectiveService flowObjectiveService;
+    protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
+    private short ttlInSecs = DEFAULT_TTL_IN_SECS_DEFAULT;
+    private int chassisId = DEFAULT_CHASSIS_ID_DEFAULT;
+    private int lldpSendPeriodicity = DEFAULT_LLDP_SEND_PERIODICITY;
+    private ApplicationId appId;
+    // Map for storing information about the neighbor connected to an OLT port
+    private EventuallyConsistentMap<ConnectPoint, OltNeighborInfo> neighbors;
+    private ScheduledFuture<?> futureTask;
+
+    protected ExecutorService packetProcessorExecutor;
+    protected ExecutorService eventExecutor;
+
+    private static boolean isNniPort(Port port) {
+        if (port.annotations().keys().contains("portName")) {
+            return port.annotations().value("portName").contains("nni-");
+        }
+        return false;
+    }
+
+    @Activate
+    public void activate(ComponentContext context) {
+        modified(context);
+        appId = coreService.registerApplication(APP_NAME);
+        componentConfigService.registerProperties(getClass());
+        codecService.registerCodec(OltNeighborInfo.class, new OltTopologyInformationCodec());
+
+        subsService = sadisService.getSubscriberInfoService();
+
+        // look for all provisioned devices in Sadis and put them in oltData
+        deviceService.getDevices().forEach(this::createAndProcessDevice);
+
+        // The NEIGHBORS map should be available across ONOS instance failures,
+        // create it using the storage service.
+        KryoNamespace serializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API)
+                .register(OltNeighborInfo.class)
+                .register(ConnectPoint.class)
+                .register(java.util.Date.class)
+                .register(org.onosproject.net.Port.class)
+                .register(org.onlab.packet.LLDPOrganizationalTLV.class)
+                .build();
+
+        neighbors = storageService.<ConnectPoint, OltNeighborInfo>eventuallyConsistentMapBuilder()
+                .withName(NEIGHBORS)
+                .withSerializer(serializer)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+
+        deviceService.addListener(deviceListener);
+
+        // register our event handler
+        packetService.addProcessor(processor, PacketProcessor.director(2));
+        futureTask = scheduledExecutorService.scheduleAtFixedRate(this::oltTopologyTimerTask, 0, lldpSendPeriodicity,
+                TimeUnit.MINUTES);
+        packetProcessorExecutor = newSingleThreadExecutor(groupedThreads("onos/olttopology", "packet-%d", log));
+        eventExecutor = newSingleThreadExecutor(groupedThreads("onos/olttopology", "events-%d", log));
+
+        log.info("Started with Application ID {}", appId.id());
+    }
+
+    @Deactivate
+    public void deactivate() {
+        futureTask.cancel(true);
+        scheduledExecutorService.shutdownNow();
+        packetService.removeProcessor(processor);
+        deviceService.removeListener(deviceListener);
+        codecService.unregisterCodec(OltNeighborInfo.class);
+        componentConfigService.unregisterProperties(getClass(), false);
+        packetProcessorExecutor.shutdown();
+        eventExecutor.shutdown();
+        log.info("Stopped");
+    }
+
+    @Modified
+    public void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
+        try {
+            String destMac = get(properties, DEFAULT_DEST_MAC_ADDRESS);
+            destMacAddress = Objects.isNull(destMac) ? DEFAULT_DEST_MAC_ADDRESS_DEFAULT : destMac;
+            String ttlInsecsStr = get(properties, DEFAULT_TTL_IN_SECS);
+            ttlInSecs = Short.parseShort(ttlInsecsStr.trim());
+
+            String chassisIdStr = get(properties, DEFAULT_CHASSIS_ID);
+            chassisId = Integer.parseInt(chassisIdStr.trim());
+
+            String lldpPeriodicity = get(properties, LLDP_SEND_PERIODICITY_STR);
+            int newLldpSendPeriodicity = Integer.parseInt(lldpPeriodicity);
+
+            if (newLldpSendPeriodicity <= 0) {
+                log.error("lldpSendPeriodicity should be a positive integer");
+            } else if (newLldpSendPeriodicity != lldpSendPeriodicity) {
+                lldpSendPeriodicity = newLldpSendPeriodicity;
+                lldpPeriodicity(newLldpSendPeriodicity);
+            }
+
+            log.debug("OLT properties: destMacAddress: {}, ttlInSecs: {}, chassisId: {}, lldpSendPeriodicity{}",
+                    destMacAddress, ttlInSecs, chassisId, lldpSendPeriodicity);
+        } catch (Exception e) {
+            log.error("Error while modifying the properties", e);
+        }
+    }
+
+    @Override
+    public Map<ConnectPoint, OltNeighborInfo> getNeighbours() {
+        return neighbors.entrySet().stream().collect(Collectors.toMap(Entry::getKey, Entry::getValue));
+    }
+
+    /**
+     * Sets periodicity in minutes for sending out LLDP packet to OLT NNI Ports.
+     *
+     * @param timer Value in minutes.
+     */
+    @Override
+    public void lldpPeriodicity(int timer) {
+        if (timer > 0) {
+            if (futureTask != null) {
+                futureTask.cancel(true);
+            }
+
+            futureTask = scheduledExecutorService.scheduleAtFixedRate(this::oltTopologyTimerTask, 0,
+                    timer,
+                    TimeUnit.MINUTES);
+            log.info("LLDP Packet out Periodicity updated to {} minutes", timer);
+        }
+    }
+
+    /**
+     * Creates entry in the oltData map.
+     * provision LLDP flow on enabled NNI ports if device is present in Sadis config
+     *
+     * @param dev Device to look for
+     */
+    private void createAndProcessDevice(Device dev) {
+        SubscriberAndDeviceInformation deviceInfo = subsService.get(dev.serialNumber());
+        log.debug("CreateAndProcessDevice: deviceInfo {}", deviceInfo);
+
+        if (deviceInfo != null) {
+            // TODO FIXME, this works only with one NNI
+            Optional<Port> optPort = deviceService.getPorts(dev.id())
+                    .stream().filter(OltTopology::isNniPort).findFirst();
+            if (optPort.isPresent()) {
+                Port port = optPort.get();
+                oltPortMap.put(dev.id(), port);
+                return;
+            }
+        }
+        log.warn("CreateAndProcessDevice: failed to update the oltdata for device {}", dev);
+    }
+
+    /**
+     * Updates OltData Map with new AccessDeviceData if it is already present in OltMap,
+     * Provisions LLDP flow on enabled NNI port if it is present in Sadis config
+     * Only one NNI port is supported as of now.
+     *
+     * @param dev    Device to look for
+     * @param uplink Uplink port number
+     * @return true if updated else false
+     */
+    private boolean updateOltData(Device dev, Port uplink) {
+        // check if this device is provisioned in Sadis
+        SubscriberAndDeviceInformation deviceInfo = subsService.get(dev.serialNumber());
+        log.debug("updateAccessDevice: deviceInfo {}", deviceInfo);
+
+        if (deviceInfo != null) {
+            oltPortMap.replace(dev.id(), uplink);
+            log.debug("updateAccessDevice: Stored did {} uplink {}", dev.id(), uplink);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sends LLDP Packet to OLT NNI Port.
+     *
+     * @param devId   Access Device data for OLT
+     * @param nniPort NNI port info of OLT
+     */
+    private void sendLldpPackets(DeviceId devId, Port nniPort) {
+        if (!mastershipService.isLocalMaster(devId)) {
+            return;
+        }
+
+        // Get NNI Port name to be filled in LLDP packet port TLV.
+        String portName = (nniPort.annotations().value("portName").isEmpty()) ? "" :
+                nniPort.annotations().value("portName");
+
+        // Get System Name value from device name.
+        Device d = deviceService.getDevice(devId);
+        String[] systemName = d.id().uri().toString().split(":", 2);
+
+        MacAddress destMac = MacAddress.valueOf(destMacAddress);
+        MacAddress srcMac = createMacFromDevId(d.id());
+
+        SubscriberAndDeviceInformation deviceInfo = subsService.get(d.serialNumber());
+
+        // Initialized deviceIP address, to be sent in Management Address TLV.
+        Ip4Address devIpAddr = Ip4Address.valueOf("0.0.0.0");
+
+        // Get OLT device IP address from deviceInfo, to be filled in management address TLV.
+        if (deviceInfo != null) {
+            devIpAddr = deviceInfo.ipAddress();
+            log.debug("sendLldpPackets: did {} nniPort {} devIP {}", d.id(), nniPort, devIpAddr);
+        } else {
+            log.warn("device {} not found in Sadis NOT sending LLDP packet", d.id());
+            return;
+        }
+
+        //Created LLDP packet.
+        Ethernet packet = createLldpPacket(destMac, srcMac, chassisId,
+                portName, ttlInSecs, systemName[1], devIpAddr
+                        .toString());
+
+        // Create the connect point to send the packet to and emit
+        ConnectPoint toSendTo = new ConnectPoint(d.id(), nniPort.number());
+
+        //Sends LLDP packet to connect point(NNI port).
+        TrafficTreatment t = DefaultTrafficTreatment.builder()
+                .setOutput(toSendTo.port()).build();
+        OutboundPacket o = new DefaultOutboundPacket(
+                toSendTo.deviceId(), t,
+                ByteBuffer.wrap(packet.serialize()));
+        if (log.isTraceEnabled()) {
+            log.trace("Sending LLDP packet {} at {}",
+                    packet, toSendTo);
+        }
+
+        packetService.emit(o);
+    }
+
+    /**
+     * Creates MAC address for LLDP packet from OLT device ID string.
+     *
+     * @param id Device ID of OLT
+     * @return Mac address
+     */
+    private MacAddress createMacFromDevId(DeviceId id) {
+        String strId = id.toString();
+        String macStr = strId.substring(7);
+        String formattedMac = macStr.replaceAll("(.{2})", "$1" + ":");
+        formattedMac = formattedMac.substring(0, formattedMac.length() - 1);
+
+        return MacAddress.valueOf(formattedMac);
+    }
+
+    /**
+     * Creates LLDP packet to be sent out of OLT.
+     *
+     * @param destMac    Destination LLDP Mac address
+     * @param srcMac     Source Mac of OLT device
+     * @param chassisId  Chassis ID TLV value
+     * @param port       NNI port information
+     * @param ttl        TTL value in sec
+     * @param systemName System name TLV value
+     * @param mgmtAddr   Management Address TLV value
+     * @return LLDP ethernet packet
+     */
+    private Ethernet createLldpPacket(MacAddress destMac, MacAddress srcMac,
+                                      int chassisId, String port, short ttl,
+                                      String systemName, String mgmtAddr) {
+
+        Ethernet ethPkt = new Ethernet();
+        ethPkt.setEtherType(Ethernet.TYPE_LLDP);
+        ethPkt.setDestinationMACAddress(destMac);
+        ethPkt.setSourceMACAddress(srcMac);
+
+        LLDP lldpPkt = new LLDP();
+
+        setChassisId(lldpPkt, chassisId);
+        setPortId(lldpPkt, port);
+        setTtl(lldpPkt, ttl);
+
+        List<LLDPTLV> optionalTlv = new ArrayList<>();
+        optionalTlv.add(createSystemNameTlv(systemName));
+        optionalTlv.add(createMgmtAddressTlv(mgmtAddr));
+
+        lldpPkt.setOptionalTLVList(optionalTlv);
+
+        ethPkt.setPayload(lldpPkt);
+        return ethPkt;
+    }
+
+    /**
+     * Sets Chassis ID TLV for LLDP packet.
+     *
+     * @param lldpPkt   LLDP packet reference
+     * @param chassisId Chassid ID tlv value
+     */
+    private void setChassisId(LLDP lldpPkt, final int chassisId) {
+        final byte chassisTlvSubtype = 1;
+
+        byte[] chassis = ArrayUtils.addAll(new byte[]{chassisTlvSubtype},
+                ByteBuffer.allocate(String.valueOf(chassisId).length())
+                        .put(String.valueOf(chassisId).getBytes()).array());
+
+        LLDPTLV chassisTlv = new LLDPTLV();
+        lldpPkt.setChassisId(chassisTlv.setLength((byte) chassis.length)
+                .setType(LLDP.CHASSIS_TLV_TYPE)
+                .setValue(chassis));
+    }
+
+    /**
+     * Sets Port ID tlv for LLDP packet.
+     *
+     * @param lldpPkt   LLDP packet reference
+     * @param ifaceName Port Name TLV value
+     */
+    private void setPortId(LLDP lldpPkt, final String ifaceName) {
+
+        byte[] port = ArrayUtils.addAll(new byte[]{PORT_TLV_SUB_TYPE},
+                ifaceName.getBytes());
+
+        LLDPTLV portTlv = new LLDPTLV();
+        lldpPkt.setPortId(portTlv.setLength((byte) port.length)
+                .setType(LLDP.PORT_TLV_TYPE)
+                .setValue(port));
+    }
+
+    /**
+     * Sets  TTL tlv for LLDP packet.
+     *
+     * @param lldpPkt    LLDP Packet reference
+     * @param timeInSecs TTL tlv value in sec
+     */
+    private void setTtl(LLDP lldpPkt, final short timeInSecs) {
+        byte[] time = ByteBuffer.allocate(2).putShort(timeInSecs).array();
+
+        LLDPTLV ttlTlv = new LLDPTLV();
+
+        lldpPkt.setTtl(ttlTlv.setType(LLDP.TTL_TLV_TYPE)
+                .setLength((short) time.length)
+                .setValue(time));
+    }
+
+    /**
+     * Creates System name TLV for LLDP packet.
+     *
+     * @param systemName System name tlv value
+     * @return systemName TLV
+     */
+    private LLDPTLV createSystemNameTlv(String systemName) {
+        byte[] bytes = systemName.getBytes();
+
+        LLDPTLV sysNameTlv = new LLDPTLV();
+
+        return sysNameTlv.setType(SYSTEMNAME_TLV_TYPE)
+                .setLength((byte) bytes.length)
+                .setValue(bytes);
+    }
+
+    /**
+     * Sets Management address TLV for LLDP packet.
+     *
+     * @param mgmtAddress Management address tlv value
+     * @return Management address TLV
+     */
+    private LLDPTLV createMgmtAddressTlv(String mgmtAddress) {
+
+        Ip4Address ipAddr = Ip4Address.valueOf(mgmtAddress);
+
+        byte[] addrStr = ArrayUtils.addAll(new byte[]{IP_ADDR_SUB_TYPE},
+                ipAddr.toOctets());
+
+        byte[] ipAddrBytes = ArrayUtils.addAll(new byte[]{IP_ADDR_STRING_LEN},
+                addrStr);
+
+        byte[] bytesInterfacetype = ArrayUtils.addAll(ipAddrBytes,
+                ByteBuffer.allocate(1).put(INTERFACE_SUB_TYPE).array());
+        byte[] bytesInterfaceNumber = ArrayUtils.addAll(bytesInterfacetype,
+                ByteBuffer.allocate(4).putInt(INTERFACE_NUM).array());
+        byte[] finalMgmtAddrBytes = ArrayUtils.addAll(bytesInterfaceNumber,
+                ByteBuffer.allocate(1).put(OID_STRING).array());
+
+        LLDPTLV mgmtAddrTlv = new LLDPTLV();
+        return mgmtAddrTlv.setType(MANAGEMENT_ADDR_TLV_TYPE)
+                .setLength((byte) finalMgmtAddrBytes.length)
+                .setValue(finalMgmtAddrBytes);
+    }
+
+    /**
+     * Processes incoming LLDP packets from NNI ports.
+     *
+     * @param pkt Inbound packet received at ONOS from OLT NNI port
+     */
+    private void handleLldpPacket(InboundPacket pkt) {
+
+        Ethernet packet = pkt.parsed();
+
+        if (packet == null) {
+            log.warn("Packet is null");
+            return;
+        }
+
+        log.debug("Got a packet {}", packet);
+
+        // Check if Ethernet type is LLDP.
+        if (packet.getEtherType() == Ethernet.TYPE_LLDP) {
+            // Get payload of Packet.
+            LLDP lldpPacket = (LLDP) packet.getPayload();
+
+            // Fetch all optional TLVs from Packet.
+            List<LLDPTLV> optionalTLVs = lldpPacket.getOptionalTLVList();
+
+            // Look for the system name and neighbor
+            // management IP address TLVs.
+            String systemName = null;
+            String neighMgmtAddr = "";
+            if (optionalTLVs != null) {
+                for (LLDPTLV tlv : optionalTLVs) {
+                    // Fetching system name TLV.
+                    if (tlv.getType() == SYSTEMNAME_TLV_TYPE) {
+                        systemName = new String(tlv.getValue());
+                    } else if (tlv.getType() == MANAGEMENT_ADDR_TLV_TYPE) {
+                        /* Fetching 4 Octets from MANAGEMENT Address TLV to get IP address. */
+                        byte[] neighMgmtIpBytes = Arrays.copyOfRange(tlv.getValue(), 2, 6);
+                        Ip4Address neighMgmtIpaddress = Ip4Address.valueOf(neighMgmtIpBytes);
+                        neighMgmtAddr = neighMgmtIpaddress.toString();
+                    }
+                }
+            }
+
+            if (systemName == null) {
+                // We expect the system name to be sent by the neighbor, in absence
+                // we don't store the information
+                return;
+            }
+
+            int portIdTlvLen = lldpPacket.getPortId().getLength();
+
+            String portName = new String(lldpPacket.getPortId().getValue())
+                    .substring(1, portIdTlvLen);
+
+            // The OLT name stored in the topology information is the device uri
+            // excluding the "of:" part
+            DeviceId devId = pkt.receivedFrom().deviceId();
+            String deviceUri = devId.uri().toString();
+            String[] oltName = deviceUri.split(":", 2);
+            Port oltNni = deviceService.getPort(pkt.receivedFrom());
+
+            String devSerial = deviceService.getDevice(devId).serialNumber();
+
+            // Creating object of OltNeighborInfo with all info required.
+            OltNeighborInfo newNeighbor = new OltNeighborInfo(systemName,
+                    portName,
+                    oltName[1],
+                    oltNni,
+                    devSerial);
+            newNeighbor.setMgmtAddress(neighMgmtAddr);
+
+            // Store all the other optional in the neighbour information
+            // this is for future use
+            for (LLDPTLV tlv : optionalTLVs) {
+                if (tlv.getType() != SYSTEMNAME_TLV_TYPE && tlv.getType() != MANAGEMENT_ADDR_TLV_TYPE) {
+                    newNeighbor.addOtherOptionalLldpTlvs(tlv);
+                }
+            }
+
+            /*
+            Checking if Neighbor information is already present.
+            If Yes, then update current information, else
+            adding new information.
+             */
+            OltNeighborInfo curNeighbor = neighbors.get(pkt.receivedFrom());
+            if (newNeighbor.equals(curNeighbor)) {
+                curNeighbor.updateTimeStamp();
+                neighbors.put(pkt.receivedFrom(), curNeighbor);
+            } else {
+                // received first time on this connect point or old was purged
+                neighbors.put(pkt.receivedFrom(), newNeighbor);
+            }
+        }
+    }
+
+    /**
+     * Removes Entry for device from Olt topology table.
+     *
+     * @param devIdToRm Device ID to be removed
+     */
+    void removeNeighborsOfDevice(DeviceId devIdToRm) {
+        for (Map.Entry<ConnectPoint, OltNeighborInfo> neighEntry : neighbors.entrySet()) {
+            if (neighEntry.getKey().deviceId().toString().contains(devIdToRm.toString())) {
+                neighbors.remove(neighEntry.getKey());
+            }
+        }
+    }
+
+    /**
+     * oltTopologyTimerTask method to send LLDP packets periodically to the neighbours.
+     */
+    public void oltTopologyTimerTask() {
+        oltPortMap.forEach((key, p) -> {
+            //Port p = deviceService.getPort(key, value);
+            if (p != null  && p.isEnabled()) {
+                sendLldpPackets(key, p);
+            }
+        });
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+        /**
+         * Device Listener Event, will be called if Device is added or state is changed or Updated.
+         *
+         * @param event Device event
+         */
+        @Override
+        public void event(DeviceEvent event) {
+            eventExecutor.execute(() -> {
+                DeviceId devId = event.subject().id();
+                /* Checking DEVICE_REMOVED and DEVICE_AVAILABILITY_CHANGED events before
+                Mastership check as with these events mastership check will always give false.
+                */
+                if (event.type().equals(DeviceEvent.Type.DEVICE_REMOVED)) {
+                    removeNeighborsOfDevice(devId);
+                    return;
+                } else if (event.type().equals(DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED)) {
+                    if (!deviceService.isAvailable(devId)) {
+                        removeNeighborsOfDevice(devId);
+                        return;
+                    }
+                }
+
+                if (!mastershipService.isLocalMaster(devId)) {
+                    return;
+                }
+
+                switch (event.type()) {
+                    case DEVICE_ADDED:
+                        if (!oltPortMap.containsKey(devId)) {
+                            createAndProcessDevice(deviceService.getDevice(devId));
+                        }
+                        break;
+                    case PORT_ADDED:
+                    /*
+                    If NNI port is detected, update it in the map.
+                     */
+                        /* TODO: put null check for the annotations return*/
+                        if (isNniPort(event.port())) {
+                            if (oltPortMap.containsKey(devId)) {
+                                if (!updateOltData(deviceService.getDevice(devId), event.port())) {
+                                    return;
+                                }
+                            } else {
+                                return;
+                            }
+                        }
+
+                        if (Objects.nonNull(oltPortMap.get(devId)) &&
+                                oltPortMap.get(devId).equals(event.port()) &&
+                                event.port().isEnabled()) {
+                            sendLldpPackets(devId, event.port());
+                        }
+                        break;
+                    case PORT_REMOVED:
+                        // Remove from neighbor map and LLDP flow if NNI port is removed.
+                        if (Objects.nonNull(oltPortMap.get(devId)) &&
+                                oltPortMap.get(devId).equals(event.port())) {
+                            // the uplink port has been removed; remove the connect
+                            // point from the neighbors
+                            neighbors.remove(new ConnectPoint(devId, event.port().number()));
+                        }
+                        break;
+                    case PORT_UPDATED:
+                        // if Port is enabled, provision LLDP flow and send LLDP packet to NNI Port.
+                        if (!oltPortMap.get(devId).equals(event.port())) {
+                            break;
+                        }
+                        if (event.port().isEnabled()) {
+                            sendLldpPackets(devId, event.port());
+                        } else {
+                            neighbors.remove(new ConnectPoint(devId, event.port().number()));
+                        }
+                        break;
+
+                    default:
+                        log.debug("event {} not handle for the device {}", event.type(), devId);
+                        break;
+                }
+            });
+        }
+    }
+
+    /*
+     * Class to do the processing of the LLDP packets received from the Packet Service.
+     */
+    private class ReactivePacketProcessor implements PacketProcessor {
+        @Override
+        public void process(PacketContext context) {
+            packetProcessorExecutor.execute(() -> {
+                DeviceId devId = context.inPacket().receivedFrom().deviceId();
+                if (!mastershipService.isLocalMaster(devId)) {
+                    return;
+                }
+                // Extract the original Ethernet frame from the packet information
+                InboundPacket pkt = context.inPacket();
+                Ethernet ethPkt = pkt.parsed();
+
+                if (ethPkt == null) {
+                    log.warn("ethPkt null while processing context: {}", context);
+                    return;
+                }
+
+                if (EthType.EtherType.lookup(ethPkt.getEtherType()) == EthType.EtherType.LLDP) {
+                    handleLldpPacket(context.inPacket());
+                }
+            });
+        }
+    }
+}
\ No newline at end of file
