diff --git a/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/DiscoveryContext.java b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/DiscoveryContext.java
new file mode 100644
index 0000000..c9c3433
--- /dev/null
+++ b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/DiscoveryContext.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.netcfglinks;
+
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.LinkKey;
+import org.onosproject.net.link.LinkProviderService;
+import org.onosproject.net.packet.PacketService;
+
+/**
+ * Shared context for use by link discovery.
+ */
+interface DiscoveryContext {
+
+    /**
+     * Returns the shared mastership service reference.
+     *
+     * @return mastership service
+     */
+    MastershipService mastershipService();
+
+    /**
+     * Returns the shared link provider service reference.
+     *
+     * @return link provider service
+     */
+    LinkProviderService providerService();
+
+    /**
+     * Returns the shared packet service reference.
+     *
+     * @return packet service
+     */
+    PacketService packetService();
+
+    /**
+     * Returns the probe rate in millis.
+     *
+     * @return probe rate
+     */
+    long probeRate();
+
+    /**
+     * Indicates whether to emit BDDP.
+     *
+     * @return true to emit BDDP
+     */
+    boolean useBddp();
+
+    /**
+     * Touches the link identified by the given key to indicate that it's active.
+     *
+     * @param key link key
+     */
+    void touchLink(LinkKey key);
+}
diff --git a/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/LinkDiscovery.java b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/LinkDiscovery.java
new file mode 100644
index 0000000..4997775
--- /dev/null
+++ b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/LinkDiscovery.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.netcfglinks;
+
+import java.nio.ByteBuffer;
+import java.util.Set;
+
+import org.jboss.netty.util.Timeout;
+import org.jboss.netty.util.TimerTask;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ONOSLLDP;
+import org.onlab.util.Timer;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link.Type;
+import org.onosproject.net.LinkKey;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.link.DefaultLinkDescription;
+import org.onosproject.net.link.LinkDescription;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.slf4j.Logger;
+
+import com.google.common.collect.Sets;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.onosproject.net.PortNumber.portNumber;
+import static org.onosproject.net.flow.DefaultTrafficTreatment.builder;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * 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.
+ */
+class LinkDiscovery implements TimerTask {
+
+    private final Logger log = getLogger(getClass());
+
+    private static final String SRC_MAC = "DE:AD:BE:EF:BA:11";
+
+    private final Device device;
+    private final DiscoveryContext context;
+
+    private final ONOSLLDP lldpPacket;
+    private final Ethernet ethPacket;
+    private final Ethernet bddpEth;
+
+    private Timeout timeout;
+    private volatile boolean isStopped;
+
+    // Set of ports to be probed
+    private final Set<Long> ports = Sets.newConcurrentHashSet();
+
+    /**
+     * 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 context discovery context
+     */
+    LinkDiscovery(Device device, DiscoveryContext context) {
+        this.device = device;
+        this.context = context;
+
+        lldpPacket = new ONOSLLDP();
+        lldpPacket.setChassisId(device.chassisId());
+        lldpPacket.setDevice(device.id().toString());
+
+        ethPacket = new Ethernet();
+        ethPacket.setEtherType(Ethernet.TYPE_LLDP);
+        ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
+        ethPacket.setPayload(this.lldpPacket);
+        ethPacket.setPad(true);
+
+        bddpEth = new Ethernet();
+        bddpEth.setPayload(lldpPacket);
+        bddpEth.setEtherType(Ethernet.TYPE_BSN);
+        bddpEth.setDestinationMACAddress(ONOSLLDP.BDDP_MULTICAST);
+        bddpEth.setPad(true);
+
+        isStopped = true;
+        start();
+        log.debug("Started discovery manager for switch {}", device.id());
+
+    }
+
+    synchronized void stop() {
+        if (!isStopped) {
+            isStopped = true;
+            timeout.cancel();
+        } else {
+            log.warn("LinkDiscovery stopped multiple times?");
+        }
+    }
+
+    synchronized void start() {
+        if (isStopped) {
+            isStopped = false;
+            timeout = Timer.getTimer().newTimeout(this, 0, MILLISECONDS);
+        } else {
+            log.warn("LinkDiscovery started multiple times?");
+        }
+    }
+
+    synchronized boolean isStopped() {
+        return isStopped || timeout.isCancelled();
+    }
+
+    /**
+     * Add physical port to discovery process.
+     * Send out initial LLDP and label it as slow port.
+     *
+     * @param port the port
+     */
+    void addPort(Port port) {
+        boolean newPort = ports.add(port.number().toLong());
+        boolean isMaster = context.mastershipService().isLocalMaster(device.id());
+        if (newPort && isMaster) {
+            log.debug("Sending initial probe to port {}@{}", port.number().toLong(), device.id());
+            sendProbes(port.number().toLong());
+        }
+    }
+
+    /**
+     * removed physical port from discovery process.
+     * @param port the port number
+     */
+    void removePort(PortNumber port) {
+        ports.remove(port.toLong());
+    }
+
+    /**
+     * Handles an incoming LLDP packet. Creates link in topology and adds the
+     * link for staleness tracking.
+     *
+     * @param packetContext packet context
+     * @return true if handled
+     */
+    boolean handleLldp(PacketContext packetContext) {
+        Ethernet eth = packetContext.inPacket().parsed();
+        if (eth == null) {
+            return false;
+        }
+
+        ONOSLLDP onoslldp = ONOSLLDP.parseONOSLLDP(eth);
+        if (onoslldp != null) {
+            PortNumber srcPort = portNumber(onoslldp.getPort());
+            PortNumber dstPort = packetContext.inPacket().receivedFrom().port();
+            DeviceId srcDeviceId = DeviceId.deviceId(onoslldp.getDeviceString());
+            DeviceId dstDeviceId = packetContext.inPacket().receivedFrom().deviceId();
+
+            ConnectPoint src = new ConnectPoint(srcDeviceId, srcPort);
+            ConnectPoint dst = new ConnectPoint(dstDeviceId, dstPort);
+
+            LinkDescription ld = eth.getEtherType() == Ethernet.TYPE_LLDP ?
+                    new DefaultLinkDescription(src, dst, Type.DIRECT, DefaultLinkDescription.EXPECTED) :
+                    new DefaultLinkDescription(src, dst, Type.INDIRECT, DefaultLinkDescription.EXPECTED);
+
+            try {
+                context.providerService().linkDetected(ld);
+                context.touchLink(LinkKey.linkKey(src, dst));
+            } catch (IllegalStateException e) {
+                return true;
+            }
+            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
+     */
+    @Override
+    public void run(Timeout t) {
+        if (isStopped()) {
+            return;
+        }
+
+        if (context.mastershipService().isLocalMaster(device.id())) {
+            log.trace("Sending probes from {}", device.id());
+            ports.forEach(this::sendProbes);
+        }
+
+        if (!isStopped()) {
+            timeout = Timer.getTimer().newTimeout(this, context.probeRate(), MILLISECONDS);
+        }
+    }
+
+    /**
+     * Creates packet_out LLDP for specified output port.
+     *
+     * @param port the port
+     * @return Packet_out message with LLDP data
+     */
+    private OutboundPacket createOutBoundLldp(Long port) {
+        if (port == null) {
+            return null;
+        }
+        lldpPacket.setPortId(port.intValue());
+        ethPacket.setSourceMACAddress(SRC_MAC);
+        return new DefaultOutboundPacket(device.id(),
+                                         builder().setOutput(portNumber(port)).build(),
+                                         ByteBuffer.wrap(ethPacket.serialize()));
+    }
+
+    /**
+     * Creates packet_out BDDP for specified output port.
+     *
+     * @param port the port
+     * @return Packet_out message with LLDP data
+     */
+    private OutboundPacket createOutBoundBddp(Long port) {
+        if (port == null) {
+            return null;
+        }
+        lldpPacket.setPortId(port.intValue());
+        bddpEth.setSourceMACAddress(SRC_MAC);
+        return new DefaultOutboundPacket(device.id(),
+                                         builder().setOutput(portNumber(port)).build(),
+                                         ByteBuffer.wrap(bddpEth.serialize()));
+    }
+
+    private void sendProbes(Long portNumber) {
+        log.trace("Sending probes out to {}@{}", portNumber, device.id());
+        OutboundPacket pkt = createOutBoundLldp(portNumber);
+        context.packetService().emit(pkt);
+        if (context.useBddp()) {
+            OutboundPacket bpkt = createOutBoundBddp(portNumber);
+            context.packetService().emit(bpkt);
+        }
+    }
+
+    boolean containsPort(long portNumber) {
+        return ports.contains(portNumber);
+    }
+
+}
diff --git a/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/NetworkConfigLinksProvider.java b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/NetworkConfigLinksProvider.java
new file mode 100644
index 0000000..edbc25c
--- /dev/null
+++ b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/NetworkConfigLinksProvider.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.netcfglinks;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ONOSLLDP;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.basics.BasicLinkConfig;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.link.DefaultLinkDescription;
+import org.onosproject.net.link.LinkProvider;
+import org.onosproject.net.link.LinkProviderRegistry;
+import org.onosproject.net.link.LinkProviderService;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.onlab.packet.Ethernet.TYPE_BSN;
+import static org.onlab.packet.Ethernet.TYPE_LLDP;
+import static org.onosproject.net.PortNumber.portNumber;
+
+/**
+ * Provider to pre-discover links and devices based on a specified network
+ * config.
+ */
+
+@Component(immediate = true)
+public class NetworkConfigLinksProvider
+        extends AbstractProvider
+        implements LinkProvider {
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkProviderRegistry providerRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService masterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry netCfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    private static final String PROP_PROBE_RATE = "probeRate";
+    private static final int DEFAULT_PROBE_RATE = 3000;
+    @Property(name = PROP_PROBE_RATE, intValue = DEFAULT_PROBE_RATE,
+            label = "LLDP and BDDP probe rate specified in millis")
+    private int probeRate = DEFAULT_PROBE_RATE;
+
+    // Device link discovery helpers.
+    protected final Map<DeviceId, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
+
+    private final DiscoveryContext context = new InternalDiscoveryContext();
+
+    private LinkProviderService providerService;
+
+    private static final String PROVIDER_NAME =
+            "org.onosproject.provider.netcfglinks";
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private ApplicationId appId;
+    private final InternalPacketProcessor packetProcessor = new InternalPacketProcessor();
+    private final InternalDeviceListener deviceListener = new InternalDeviceListener();
+    private final InternalConfigListener cfgListener = new InternalConfigListener();
+
+    private Set<LinkKey> configuredLinks = new HashSet<>();
+
+    public NetworkConfigLinksProvider() {
+        super(new ProviderId("lldp", PROVIDER_NAME));
+    }
+
+    private void createLinks() {
+        netCfgService.getSubjects(LinkKey.class)
+                .forEach(linkKey -> configuredLinks.add(linkKey));
+    }
+
+    @Activate
+    protected void activate() {
+        log.info("Activated");
+        appId = coreService.registerApplication(PROVIDER_NAME);
+        packetService.addProcessor(packetProcessor, PacketProcessor.advisor(0));
+        providerService = providerRegistry.register(this);
+        deviceService.addListener(deviceListener);
+        netCfgService.addListener(cfgListener);
+        requestIntercepts();
+        loadDevices();
+        createLinks();
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        withdrawIntercepts();
+        providerRegistry.unregister(this);
+        disable();
+        log.info("Deactivated");
+    }
+
+    /**
+     * Loads available devices and registers their ports to be probed.
+     */
+    private void loadDevices() {
+        deviceService.getAvailableDevices()
+                .forEach(d -> updateDevice(d)
+                        .ifPresent(ld -> updatePorts(ld, d.id())));
+    }
+
+    private Optional<LinkDiscovery> updateDevice(Device device) {
+        if (device == null) {
+            return Optional.empty();
+        }
+
+        LinkDiscovery ld = discoverers.computeIfAbsent(device.id(),
+                                                       did -> new LinkDiscovery(device, context));
+        if (ld.isStopped()) {
+            ld.start();
+        }
+        return Optional.of(ld);
+    }
+
+    /**
+     * Updates ports of the specified device to the specified discovery helper.
+     */
+    private void updatePorts(LinkDiscovery discoverer, DeviceId deviceId) {
+        deviceService.getPorts(deviceId).forEach(p -> updatePort(discoverer, p));
+    }
+
+
+    private void updatePort(LinkDiscovery discoverer, Port port) {
+        if (port == null) {
+            return;
+        }
+        if (port.number().isLogical()) {
+            // silently ignore logical ports
+            return;
+        }
+
+        discoverer.addPort(port);
+    }
+
+    /**
+     * Disables link discovery processing.
+     */
+    private void disable() {
+
+        providerRegistry.unregister(this);
+        discoverers.values().forEach(LinkDiscovery::stop);
+        discoverers.clear();
+
+        providerService = null;
+    }
+
+    /**
+     * Provides processing context for the device link discovery helpers.
+     */
+    private class InternalDiscoveryContext implements DiscoveryContext {
+        @Override
+        public MastershipService mastershipService() {
+            return masterService;
+        }
+
+        @Override
+        public LinkProviderService providerService() {
+            return providerService;
+        }
+
+        @Override
+        public PacketService packetService() {
+            return packetService;
+        }
+
+        @Override
+        public long probeRate() {
+            return probeRate;
+        }
+
+        @Override
+        public boolean useBddp() {
+            return true;
+        }
+
+        @Override
+        public void touchLink(LinkKey key) {
+            //linkTimes.put(key, System.currentTimeMillis());
+        }
+    }
+
+    LinkKey extractLinkKey(PacketContext packetContext) {
+        Ethernet eth = packetContext.inPacket().parsed();
+        if (eth == null) {
+            return null;
+        }
+
+        ONOSLLDP onoslldp = ONOSLLDP.parseONOSLLDP(eth);
+        if (onoslldp != null) {
+            PortNumber srcPort = portNumber(onoslldp.getPort());
+            PortNumber dstPort = packetContext.inPacket().receivedFrom().port();
+            DeviceId srcDeviceId = DeviceId.deviceId(onoslldp.getDeviceString());
+            DeviceId dstDeviceId = packetContext.inPacket().receivedFrom().deviceId();
+
+            ConnectPoint src = new ConnectPoint(srcDeviceId, srcPort);
+            ConnectPoint dst = new ConnectPoint(dstDeviceId, dstPort);
+            return LinkKey.linkKey(src, dst);
+        }
+        return null;
+    }
+
+    /**
+     * Processes incoming packets.
+     */
+    private class InternalPacketProcessor implements PacketProcessor {
+        @Override
+        public void process(PacketContext context) {
+            if (context == null || context.isHandled()) {
+                return;
+            }
+
+            Ethernet eth = context.inPacket().parsed();
+            if (eth == null || (eth.getEtherType() != TYPE_LLDP && eth.getEtherType() != TYPE_BSN)) {
+                return;
+            }
+
+            InboundPacket inPacket = context.inPacket();
+            LinkKey linkKey = extractLinkKey(context);
+            if (linkKey != null) {
+                if (configuredLinks.contains(linkKey)) {
+                    log.debug("Found configured link {}", linkKey);
+                    LinkDiscovery ld = discoverers.get(inPacket.receivedFrom().deviceId());
+                    if (ld == null) {
+                        return;
+                    }
+                    if (ld.handleLldp(context)) {
+                        context.block();
+                    }
+                } else {
+                    log.debug("Found link that was not in the configuration {}", linkKey);
+                    providerService.linkDetected(
+                            new DefaultLinkDescription(linkKey.src(),
+                                                       linkKey.dst(),
+                                                       Link.Type.DIRECT,
+                                                       DefaultLinkDescription.NOT_EXPECTED,
+                                                       DefaultAnnotations.EMPTY));
+                }
+            }
+        }
+    }
+
+    /**
+     * Requests packet intercepts.
+     */
+    private void requestIntercepts() {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(TYPE_LLDP);
+        packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
+                                     appId, Optional.empty());
+
+        selector.matchEthType(TYPE_BSN);
+
+        packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
+                                     appId, Optional.empty());
+
+    }
+
+    /**
+     * Withdraws packet intercepts.
+     */
+    private void withdrawIntercepts() {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(TYPE_LLDP);
+        packetService.cancelPackets(selector.build(), PacketPriority.CONTROL,
+                                    appId, Optional.empty());
+        selector.matchEthType(TYPE_BSN);
+        packetService.cancelPackets(selector.build(), PacketPriority.CONTROL,
+                                    appId, Optional.empty());
+    }
+
+    /**
+     * Processes device events.
+     */
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            if (event.type() == DeviceEvent.Type.PORT_STATS_UPDATED) {
+                return;
+            }
+            Device device = event.subject();
+            Port port = event.port();
+            if (device == null) {
+                log.error("Device is null.");
+                return;
+            }
+            log.trace("{} {} {}", event.type(), event.subject(), event);
+            final DeviceId deviceId = device.id();
+            switch (event.type()) {
+                case DEVICE_ADDED:
+                case DEVICE_UPDATED:
+                    updateDevice(device).ifPresent(ld -> updatePorts(ld, deviceId));
+                    break;
+                case PORT_ADDED:
+                case PORT_UPDATED:
+                    if (port.isEnabled()) {
+                        updateDevice(device).ifPresent(ld -> updatePort(ld, port));
+                    } else {
+                        log.debug("Port down {}", port);
+                        //removePort(port);
+                        providerService.linksVanished(new ConnectPoint(port.element().id(),
+                                                                       port.number()));
+                    }
+                    break;
+                case PORT_REMOVED:
+                    log.debug("Port removed {}", port);
+                    //removePort(port);
+                    providerService.linksVanished(new ConnectPoint(port.element().id(),
+                                                                   port.number()));
+                    break;
+                case DEVICE_REMOVED:
+                case DEVICE_SUSPENDED:
+                    log.debug("Device removed {}", deviceId);
+                    //removeDevice(deviceId);
+                    providerService.linksVanished(deviceId);
+                    break;
+                case DEVICE_AVAILABILITY_CHANGED:
+                    if (deviceService.isAvailable(deviceId)) {
+                        log.debug("Device up {}", deviceId);
+                        updateDevice(device).ifPresent(ld -> updatePorts(ld, deviceId));
+                    } else {
+                        log.debug("Device down {}", deviceId);
+                        //removeDevice(deviceId);
+                        providerService.linksVanished(deviceId);
+                    }
+                    break;
+                case PORT_STATS_UPDATED:
+                    break;
+                default:
+                    log.debug("Unknown event {}", event);
+            }
+        }
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        private void addLink(LinkKey linkKey) {
+            configuredLinks.add(linkKey);
+        }
+
+        private void removeLink(LinkKey linkKey) {
+            DefaultLinkDescription linkDescription =
+                    new DefaultLinkDescription(linkKey.src(), linkKey.dst(),
+                                               Link.Type.DIRECT);
+            configuredLinks.remove(linkKey);
+            providerService.linkVanished(linkDescription);
+        }
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+
+            if (event.configClass().equals(BasicLinkConfig.class)) {
+                log.info("net config event of type {} for basic link {}",
+                         event.type(), event.subject());
+                LinkKey linkKey = (LinkKey) event.subject();
+                if (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED) {
+                    addLink(linkKey);
+                } else if (event.type() == NetworkConfigEvent.Type.CONFIG_REMOVED) {
+                    removeLink(linkKey);
+                }
+            }
+            log.info("Reconfigured");
+        }
+    }
+
+}
diff --git a/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/package-info.java b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/package-info.java
new file mode 100644
index 0000000..1701b0a
--- /dev/null
+++ b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2015 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.
+ */
+
+/**
+ * Provider to pre-discover links and devices based on a specified network
+ * config.
+ */
+package org.onosproject.provider.netcfglinks;
