diff --git a/app/src/main/java/org/opencord/olttopology/cli/OltTopologyGetCommand.java b/app/src/main/java/org/opencord/olttopology/cli/OltTopologyGetCommand.java
new file mode 100644
index 0000000..7acbac8
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/cli/OltTopologyGetCommand.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2017-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.cli;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
+import org.opencord.olttopology.OltNeighborInfo;
+import org.opencord.olttopology.OltTopologyInformationService;
+
+import java.util.Map;
+
+/**
+ * OLT Topology CLI Command.
+ * <p>
+ * Shows the current topology in the CLI.
+ */
+@Service
+@Command(scope = "onos", name = "olt-topology", description = "OLT Topology CLI command")
+public class OltTopologyGetCommand extends AbstractShellCommand {
+
+    private static final String FORMAT = "%s";
+
+    private OltTopologyInformationService oltTopoSer = get(OltTopologyInformationService.class);
+
+    @Override
+    protected void doExecute() {
+        oltTopoSer.getNeighbours().entrySet().forEach(this::display);
+    }
+
+    private void display(Map.Entry<ConnectPoint, OltNeighborInfo> neighbor) {
+        print(FORMAT, neighbor.getValue());
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/opencord/olttopology/cli/package-info.java b/app/src/main/java/org/opencord/olttopology/cli/package-info.java
new file mode 100644
index 0000000..2e664a7
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-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.
+ */
+
+/**
+ * OLT application handling PMC OLT hardware.
+ */
+package org.opencord.olttopology.cli;
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
diff --git a/app/src/main/java/org/opencord/olttopology/impl/OltTopologyInformationCodec.java b/app/src/main/java/org/opencord/olttopology/impl/OltTopologyInformationCodec.java
new file mode 100644
index 0000000..bd45bed
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/impl/OltTopologyInformationCodec.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2017-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 com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.packet.LLDPTLV;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.opencord.olttopology.OltNeighborInfo;
+
+import java.util.Date;
+import java.util.List;
+
+/*
+Codec for JSON encoding of OLT topology information.
+ */
+public class OltTopologyInformationCodec extends JsonCodec<OltNeighborInfo> {
+    /**
+     * Encoder for the information in Json format.
+     *
+     * @param en      : The topology information to be encoded
+     * @param context : The context to which the Json data needs to be added
+     * @return Json Object Node
+     */
+    @Override
+    public ObjectNode encode(OltNeighborInfo en, CodecContext context) {
+        final ObjectNode result = context.mapper().createObjectNode()
+                .put("oltName", (en.oltName() == null) ? "" : en.oltName())
+                .put("oltPort", (en.oltPort().annotations().value("portName").isEmpty()) ? "" :
+                        en.oltPort().annotations().value("portName"))
+                .put("oltSerialNo", (en.oltSerialNo() == null) ? "" : en.oltSerialNo())
+                .put("neighborName", (en.neighborName() == null) ? "" : en.neighborName())
+                .put("neighborPort", (en.neighborPort() == null) ? "" : en.neighborPort())
+                .put("neighborManagementAddress", (en.mgmtAddr() == null) ? "" : en.mgmtAddr());
+
+        if (en.getOtherOptionalTlvs() != null) {
+            ArrayNode optionalTlvNodes = result.putArray("optionalTlvs");
+
+            List<LLDPTLV> optionalTlvsList = en.getOtherOptionalTlvs();
+            for (LLDPTLV tlv : optionalTlvsList) {
+                ObjectNode optionalTlvNode = context.mapper().createObjectNode();
+                optionalTlvNode.put("type", tlv.getType());
+                optionalTlvNode.put("value", "0x" + byteArrayInHex(tlv.getValue()));
+                optionalTlvNodes.add(optionalTlvNode);
+            }
+        }
+
+        Date currentTime = new Date();
+        long lastUpdatedValue = currentTime.getTime() - en.getLastUpdated().getTime();
+        long lastUpdatedSecondsValue = lastUpdatedValue / 1000;
+        result.put("last_updated", Long.toString(lastUpdatedSecondsValue));
+        return result;
+    }
+
+    /**
+     * Utility function to convert byte array to Hex String.
+     *
+     * @param bytes : The byte arrary to be converted
+     * @return Hex string representation of the byte array
+     */
+    private String byteArrayInHex(byte[] bytes) {
+        String s = "";
+        for (byte b : bytes) {
+            s += String.format("%02x", b);
+        }
+        return s;
+    }
+}
diff --git a/app/src/main/java/org/opencord/olttopology/impl/OsgiPropertyConstants.java b/app/src/main/java/org/opencord/olttopology/impl/OsgiPropertyConstants.java
new file mode 100644
index 0000000..c05d219
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/impl/OsgiPropertyConstants.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2019-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;
+
+/**
+ * Constants for default values of configurable properties.
+ */
+public final class OsgiPropertyConstants {
+    public static final String DEFAULT_DEST_MAC_ADDRESS = "destMacAddress";
+    // Destination Mac address where LLDP packet has to be sent.
+    public static final String DEFAULT_DEST_MAC_ADDRESS_DEFAULT = "01:80:c2:00:00:00";
+    public static final String DEFAULT_TTL_IN_SECS = "ttlInSecs";
+    // Default Time To Live value to be used in the LLDP packets sent out
+    public static final int DEFAULT_TTL_IN_SECS_DEFAULT = 120;
+    public static final String DEFAULT_CHASSIS_ID = "chassisId";
+    // Default ChassisId to be used in the LLDP packets sent out
+    public static final int DEFAULT_CHASSIS_ID_DEFAULT = 0;
+    // Default periodicity (in minutes) of sending the LLDP messages through OLT NNI Ports
+    public static final int DEFAULT_LLDP_SEND_PERIODICITY = 15;
+    public static final String LLDP_SEND_PERIODICITY_STR = "lldpSendPeriodicity";
+
+    private OsgiPropertyConstants() {
+    }
+}
diff --git a/app/src/main/java/org/opencord/olttopology/impl/package-info.java b/app/src/main/java/org/opencord/olttopology/impl/package-info.java
new file mode 100644
index 0000000..7104a76
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-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.
+ */
+
+/**
+ * OLT Topology application for finding the topology of OLTs.
+ */
+package org.opencord.olttopology.impl;
diff --git a/app/src/main/java/org/opencord/olttopology/rest/OltTopologyWebResource.java b/app/src/main/java/org/opencord/olttopology/rest/OltTopologyWebResource.java
new file mode 100644
index 0000000..bbd8f79
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/rest/OltTopologyWebResource.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017-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.rest;
+import org.onosproject.rest.AbstractWebResource;
+import org.opencord.olttopology.OltNeighborInfo;
+import org.opencord.olttopology.OltTopologyInformationService;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+/**
+ * OltTopology Information Service web resource.
+ */
+@Path("oltTopologyApp")
+public class OltTopologyWebResource extends AbstractWebResource {
+    private final OltTopologyInformationService service = get(OltTopologyInformationService.class);
+    /**
+     * Shows the information about the connectivity between the
+     * ports of the OLT and ports of the leaf switch.
+     *
+     * @return 200 OK
+     */
+    @GET
+    @Path("show")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getOltTopology() {
+        Iterable<OltNeighborInfo> neighbourInfos = service.getNeighbours().values();
+        return ok(encodeArray(OltNeighborInfo.class, "entries", neighbourInfos).toString()).build();
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/opencord/olttopology/rest/package-info.java b/app/src/main/java/org/opencord/olttopology/rest/package-info.java
new file mode 100644
index 0000000..684d60d
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/rest/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-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.
+ */
+
+/**
+ * REST APIs for the OltTopology application.
+ */
+package org.opencord.olttopology.rest;
