diff --git a/providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LinkDiscovery.java b/providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LinkDiscovery.java
new file mode 100644
index 0000000..fc0a0f4
--- /dev/null
+++ b/providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LinkDiscovery.java
@@ -0,0 +1,349 @@
+/*******************************************************************************
+ * Copyright 2014 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.onlab.onos.provider.lldp.impl;
+
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.jboss.netty.util.Timeout;
+import org.jboss.netty.util.TimerTask;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.Device;
+import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.Link.Type;
+import org.onlab.onos.net.Port;
+import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.flow.DefaultTrafficTreatment;
+import org.onlab.onos.net.link.DefaultLinkDescription;
+import org.onlab.onos.net.link.LinkDescription;
+import org.onlab.onos.net.link.LinkProviderService;
+import org.onlab.onos.net.packet.DefaultOutboundPacket;
+import org.onlab.onos.net.packet.OutboundPacket;
+import org.onlab.onos.net.packet.PacketContext;
+import org.onlab.onos.net.packet.PacketService;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ONOSLLDP;
+import org.onlab.util.Timer;
+import org.slf4j.Logger;
+
+
+
+/**
+ * Run discovery process from a physical switch. Ports are initially labeled as
+ * slow ports. When an LLDP is successfully received, label the remote port as
+ * fast. Every probeRate milliseconds, loop over all fast ports and send an
+ * LLDP, send an LLDP for a single slow port. Based on FlowVisor topology
+ * discovery implementation.
+ *
+ * TODO: add 'fast discovery' mode: drop LLDPs in destination switch but listen
+ * for flow_removed messages
+ */
+public class LinkDiscovery implements TimerTask {
+
+    private final Device device;
+    // send 1 probe every probeRate milliseconds
+    private final long probeRate;
+    private final Set<Long> slowPorts;
+    private final Set<Long> fastPorts;
+    // number of unacknowledged probes per port
+    private final Map<Long, AtomicInteger> portProbeCount;
+    // number of probes to send before link is removed
+    private static final short MAX_PROBE_COUNT = 3;
+    private final Logger log = getLogger(getClass());
+    private final ONOSLLDP lldpPacket;
+    private final Ethernet ethPacket;
+    private Ethernet bddpEth;
+    private final boolean useBDDP;
+    private final LinkProviderService linkProvider;
+    private final PacketService pktService;
+    private Timeout timeout;
+
+    /**
+     * Instantiates discovery manager for the given physical switch. Creates a
+     * generic LLDP packet that will be customized for the port it is sent out on.
+     * Starts the the timer for the discovery process.
+     *
+     * @param device the physical switch
+     * @param useBDDP flag to also use BDDP for discovery
+     */
+    public LinkDiscovery(Device device, PacketService pktService,
+             LinkProviderService providerService, Boolean... useBDDP) {
+        this.device = device;
+        this.probeRate = 3000;
+        this.linkProvider = providerService;
+        this.pktService = pktService;
+        this.slowPorts = Collections.synchronizedSet(new HashSet<Long>());
+        this.fastPorts = Collections.synchronizedSet(new HashSet<Long>());
+        this.portProbeCount = new HashMap<>();
+        this.lldpPacket = new ONOSLLDP();
+        this.lldpPacket.setChassisId(device.chassisId());
+        this.lldpPacket.setDevice(device.id().toString());
+
+
+        this.ethPacket = new Ethernet();
+        this.ethPacket.setEtherType(Ethernet.TYPE_LLDP);
+        this.ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
+        this.ethPacket.setPayload(this.lldpPacket);
+        this.ethPacket.setPad(true);
+        this.useBDDP = useBDDP.length > 0 ? useBDDP[0] : false;
+        if (this.useBDDP) {
+            this.bddpEth = new Ethernet();
+            this.bddpEth.setPayload(this.lldpPacket);
+            this.bddpEth.setEtherType(Ethernet.TYPE_BSN);
+            this.bddpEth.setDestinationMACAddress(ONOSLLDP.BDDP_MULTICAST);
+            this.bddpEth.setPad(true);
+            log.info("Using BDDP to discover network");
+        }
+
+        start();
+        this.log.debug("Started discovery manager for switch {}",
+                       device.id());
+
+    }
+
+    /**
+     * Add physical port port to discovery process.
+     * Send out initial LLDP and label it as slow port.
+     *
+     * @param port the port
+     */
+    public void addPort(final Port port) {
+        this.log.debug("sending init probe to port {}",
+                           port.number().toLong());
+
+        sendProbes(port.number().toLong());
+
+        synchronized (this) {
+            this.slowPorts.add(port.number().toLong());
+        }
+
+
+    }
+
+    /**
+     * Removes physical port from discovery process.
+     *
+     * @param port the port
+     */
+    public void removePort(final Port port) {
+        // Ignore ports that are not on this switch
+
+        long portnum = port.number().toLong();
+        synchronized (this) {
+            if (this.slowPorts.contains(portnum)) {
+                this.slowPorts.remove(portnum);
+
+            } else if (this.fastPorts.contains(portnum)) {
+                this.fastPorts.remove(portnum);
+                this.portProbeCount.remove(portnum);
+                // no iterator to update
+            } else {
+                this.log.warn(
+                        "tried to dynamically remove non-existing port {}",
+                        portnum);
+            }
+        }
+    }
+
+    /**
+     * Method called by remote port to acknowledge receipt of LLDP sent by
+     * this port. If slow port, updates label to fast. If fast port, decrements
+     * number of unacknowledged probes.
+     *
+     * @param portNumber the port
+     */
+    public void ackProbe(final Long portNumber) {
+
+        synchronized (this) {
+            if (this.slowPorts.contains(portNumber)) {
+                this.log.debug("Setting slow port to fast: {}:{}",
+                        this.device.id(), portNumber);
+                this.slowPorts.remove(portNumber);
+                this.fastPorts.add(portNumber);
+                this.portProbeCount.put(portNumber, new AtomicInteger(0));
+            } else {
+                if (this.fastPorts.contains(portNumber)) {
+                    this.portProbeCount.get(portNumber).set(0);
+                } else {
+                    this.log.debug(
+                            "Got ackProbe for non-existing port: {}",
+                            portNumber);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Handles an incoming LLDP packet. Creates link in topology and sends ACK
+     * to port where LLDP originated.
+     */
+    public boolean handleLLDP(PacketContext context) {
+        Ethernet eth = context.inPacket().parsed();
+        ONOSLLDP onoslldp = ONOSLLDP.parseONOSLLDP(eth);
+        if (onoslldp != null) {
+            final PortNumber dstPort =
+                    context.inPacket().receivedFrom().port();
+            final PortNumber srcPort = PortNumber.portNumber(onoslldp.getPort());
+            final DeviceId srcDeviceId = DeviceId.deviceId(onoslldp.getDeviceString());
+            final DeviceId dstDeviceId = context.inPacket().receivedFrom().deviceId();
+            this.ackProbe(srcPort.toLong());
+            ConnectPoint src = new ConnectPoint(srcDeviceId, srcPort);
+            ConnectPoint dst = new ConnectPoint(dstDeviceId, dstPort);
+
+            LinkDescription ld;
+            if (eth.getEtherType() == Ethernet.TYPE_BSN) {
+                ld = new DefaultLinkDescription(src, dst, Type.INDIRECT);
+            } else {
+                ld = new DefaultLinkDescription(src, dst, Type.DIRECT);
+            }
+            linkProvider.linkDetected(ld);
+            return true;
+        }
+        return false;
+    }
+
+
+
+    /**
+     * Execute this method every t milliseconds. Loops over all ports
+     * labeled as fast and sends out an LLDP. Send out an LLDP on a single slow
+     * port.
+     *
+     * @param t timeout
+     * @throws Exception
+     */
+    @Override
+    public void run(final Timeout t) {
+        this.log.debug("sending probes");
+        synchronized (this) {
+            final Iterator<Long> fastIterator = this.fastPorts.iterator();
+            Long portNumber;
+            Integer probeCount;
+            while (fastIterator.hasNext()) {
+                portNumber = fastIterator.next();
+                probeCount = this.portProbeCount.get(portNumber)
+                        .getAndIncrement();
+
+                if (probeCount < LinkDiscovery.MAX_PROBE_COUNT) {
+                    this.log.debug("sending fast probe to port");
+                    sendProbes(portNumber);
+                } else {
+                    // Update fast and slow ports
+                    //fastIterator.remove();
+                    //this.slowPorts.add(portNumber);
+                    //this.portProbeCount.remove(portNumber);
+
+
+                    ConnectPoint cp = new ConnectPoint(
+                            device.id(),
+                            PortNumber.portNumber(portNumber));
+                    log.debug("Link down -> {}", cp);
+                    linkProvider.linksVanished(cp);
+                }
+            }
+
+            // send a probe for the next slow port
+            if (!this.slowPorts.isEmpty()) {
+                Iterator<Long> slowIterator = this.slowPorts.iterator();
+                while (slowIterator.hasNext()) {
+                    portNumber = slowIterator.next();
+                    this.log.debug("sending slow probe to port {}", portNumber);
+
+                    sendProbes(portNumber);
+
+                }
+            }
+        }
+
+        // reschedule timer
+        timeout = Timer.getTimer().newTimeout(this, this.probeRate,
+                TimeUnit.MILLISECONDS);
+    }
+
+    public void stop() {
+        timeout.cancel();
+    }
+
+    public void start() {
+        timeout = Timer.getTimer().newTimeout(this, 0,
+                                              TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Creates packet_out LLDP for specified output port.
+     *
+     * @param port the port
+     * @return Packet_out message with LLDP data
+     */
+    private OutboundPacket createOutBoundLLDP(final Long port) {
+        if (port == null) {
+            return null;
+        }
+        this.lldpPacket.setPortId(port.intValue());
+        this.ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
+
+        final byte[] lldp = this.ethPacket.serialize();
+        OutboundPacket outboundPacket = new DefaultOutboundPacket(
+                this.device.id(),
+                DefaultTrafficTreatment.builder().setOutput(
+                        PortNumber.portNumber(port)).build(),
+                ByteBuffer.wrap(lldp));
+        return outboundPacket;
+    }
+
+    /**
+     * Creates packet_out BDDP for specified output port.
+     *
+     * @param port the port
+     * @return Packet_out message with LLDP data
+     */
+    private OutboundPacket createOutBoundBDDP(final Long port) {
+        if (port == null) {
+            return null;
+        }
+        this.lldpPacket.setPortId(port.intValue());
+        this.bddpEth.setSourceMACAddress("DE:AD:BE:EF:BA:11");
+
+        final byte[] bddp = this.bddpEth.serialize();
+        OutboundPacket outboundPacket = new DefaultOutboundPacket(
+                this.device.id(),
+                DefaultTrafficTreatment.builder()
+                        .setOutput(PortNumber.portNumber(port)).build(),
+                ByteBuffer.wrap(bddp));
+        return outboundPacket;
+    }
+
+    private void sendProbes(Long portNumber) {
+        OutboundPacket pkt = this.createOutBoundLLDP(portNumber);
+        pktService.emit(pkt);
+        if (useBDDP) {
+            OutboundPacket bpkt = this.createOutBoundBDDP(portNumber);
+            pktService.emit(bpkt);
+        }
+    }
+
+}
