diff --git a/core/net/src/main/java/org/onosproject/net/resource/impl/ResourceDeviceListener.java b/core/net/src/main/java/org/onosproject/net/resource/impl/ResourceDeviceListener.java
new file mode 100644
index 0000000..1cd47aa
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/resource/impl/ResourceDeviceListener.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2015-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.net.resource.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onlab.util.Bandwidth;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TributarySlot;
+import org.onosproject.net.behaviour.LambdaQuery;
+import org.onosproject.net.behaviour.MplsQuery;
+import org.onosproject.net.behaviour.TributarySlotQuery;
+import org.onosproject.net.behaviour.VlanQuery;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.resource.DiscreteResource;
+import org.onosproject.net.resource.ResourceAdminService;
+import org.onosproject.net.resource.BandwidthCapacity;
+import org.onosproject.net.resource.Resource;
+import org.onosproject.net.resource.Resources;
+import org.onosproject.net.resource.ResourceService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * An implementation of DeviceListener registering devices as resources.
+ */
+final class ResourceDeviceListener implements DeviceListener {
+
+    private static final Logger log = LoggerFactory.getLogger(ResourceDeviceListener.class);
+
+    private final ResourceAdminService adminService;
+    private final ResourceService resourceService;
+    private final DeviceService deviceService;
+    private final MastershipService mastershipService;
+    private final DriverService driverService;
+    private final NetworkConfigService netcfgService;
+    private final ExecutorService executor;
+
+
+    /**
+     * Creates an instance with the specified ResourceAdminService and ExecutorService.
+     *
+     * @param adminService instance invoked to register resources
+     * @param resourceService {@link ResourceService} to be used
+     * @param deviceService {@link DeviceService} to be used
+     * @param mastershipService {@link MastershipService} to be used
+     * @param driverService {@link DriverService} to be used
+     * @param netcfgService {@link NetworkConfigService} to be used.
+     * @param executor executor used for processing resource registration
+     */
+    ResourceDeviceListener(ResourceAdminService adminService, ResourceService resourceService,
+                           DeviceService deviceService, MastershipService mastershipService,
+                           DriverService driverService, NetworkConfigService netcfgService,
+                           ExecutorService executor) {
+        this.adminService = checkNotNull(adminService);
+        this.resourceService = checkNotNull(resourceService);
+        this.deviceService = checkNotNull(deviceService);
+        this.mastershipService = checkNotNull(mastershipService);
+        this.driverService = checkNotNull(driverService);
+        this.netcfgService = checkNotNull(netcfgService);
+        this.executor = checkNotNull(executor);
+    }
+
+    @Override
+    public void event(DeviceEvent event) {
+        Device device = event.subject();
+        // registration happens only when the caller is the master of the device
+        if (!mastershipService.isLocalMaster(device.id())) {
+            return;
+        }
+
+        switch (event.type()) {
+            case DEVICE_ADDED:
+                registerDeviceResource(device);
+                break;
+            case DEVICE_REMOVED:
+                unregisterDeviceResource(device);
+                break;
+            case DEVICE_AVAILABILITY_CHANGED:
+                if (deviceService.isAvailable(device.id())) {
+                    registerDeviceResource(device);
+                    // TODO: do we need to walk the ports?
+                } else {
+                    unregisterDeviceResource(device);
+                }
+                break;
+            case PORT_ADDED:
+            case PORT_UPDATED:
+                if (event.port().isEnabled()) {
+                    registerPortResource(device, event.port());
+                } else {
+                    unregisterPortResource(device, event.port());
+                }
+                break;
+            case PORT_REMOVED:
+                unregisterPortResource(device, event.port());
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void registerDeviceResource(Device device) {
+        executor.execute(() -> adminService.register(Resources.discrete(device.id()).resource()));
+    }
+
+    private void unregisterDeviceResource(Device device) {
+        executor.execute(() -> {
+            DiscreteResource devResource = Resources.discrete(device.id()).resource();
+            List<Resource> allResources = getDescendantResources(devResource);
+            adminService.unregister(Lists.transform(allResources, Resource::id));
+        });
+    }
+
+    private void registerPortResource(Device device, Port port) {
+        Resource portPath = Resources.discrete(device.id(), port.number()).resource();
+        executor.execute(() -> {
+            adminService.register(portPath);
+
+            queryBandwidth(device.id(), port.number())
+                .map(bw -> portPath.child(Bandwidth.class, bw.bps()))
+                .map(adminService::register)
+                .ifPresent(success -> {
+                   if (!success) {
+                       log.error("Failed to register Bandwidth for {}", portPath.id());
+                   }
+                });
+
+            // for VLAN IDs
+            Set<VlanId> vlans = queryVlanIds(device.id(), port.number());
+            if (!vlans.isEmpty()) {
+                adminService.register(vlans.stream()
+                        .map(portPath::child)
+                        .collect(Collectors.toList()));
+            }
+
+            // for MPLS labels
+            Set<MplsLabel> mplsLabels = queryMplsLabels(device.id(), port.number());
+            if (!mplsLabels.isEmpty()) {
+                adminService.register(mplsLabels.stream()
+                        .map(portPath::child)
+                        .collect(Collectors.toList()));
+            }
+
+            // for Lambdas
+            Set<OchSignal> lambdas = queryLambdas(device.id(), port.number());
+            if (!lambdas.isEmpty()) {
+                adminService.register(lambdas.stream()
+                        .map(portPath::child)
+                        .collect(Collectors.toList()));
+            }
+
+            // for Tributary slots
+            Set<TributarySlot> tSlots = queryTributarySlots(device.id(), port.number());
+            if (!tSlots.isEmpty()) {
+                adminService.register(tSlots.stream()
+                        .map(portPath::child)
+                        .collect(Collectors.toList()));
+            }
+        });
+    }
+
+    private void unregisterPortResource(Device device, Port port) {
+        executor.execute(() -> {
+            DiscreteResource portResource = Resources.discrete(device.id(), port.number()).resource();
+            List<Resource> allResources = getDescendantResources(portResource);
+            adminService.unregister(Lists.transform(allResources, Resource::id));
+        });
+    }
+
+    // Returns list of all descendant resources of given resource, including itself.
+    private List<Resource> getDescendantResources(DiscreteResource parent) {
+        LinkedList<Resource> allResources = new LinkedList<>();
+        allResources.add(parent);
+
+        Set<Resource> nextResources = resourceService.getRegisteredResources(parent.id());
+        while (!nextResources.isEmpty()) {
+            Set<Resource> currentResources = nextResources;
+            // resource list should be ordered from leaf to root
+            allResources.addAll(0, currentResources);
+
+            nextResources = currentResources.stream()
+                    .filter(r -> r instanceof DiscreteResource)
+                    .map(r -> (DiscreteResource) r)
+                    .flatMap(r -> resourceService.getRegisteredResources(r.id()).stream())
+                    .collect(Collectors.toSet());
+        }
+
+        return allResources;
+    }
+
+    /**
+     * Query bandwidth capacity on a port.
+     *
+     * @param did {@link DeviceId}
+     * @param number {@link PortNumber}
+     * @return bandwidth capacity
+     */
+    private Optional<Bandwidth> queryBandwidth(DeviceId did, PortNumber number) {
+        // Check and use netcfg first.
+        ConnectPoint cp = new ConnectPoint(did, number);
+        BandwidthCapacity config = netcfgService.getConfig(cp, BandwidthCapacity.class);
+        if (config != null) {
+            log.trace("Registering configured bandwidth {} for {}/{}", config.capacity(), did, number);
+            return Optional.of(config.capacity());
+        }
+
+        // populate bandwidth value, assuming portSpeed == bandwidth
+        Port port = deviceService.getPort(did, number);
+        if (port != null) {
+            return Optional.of(Bandwidth.mbps(port.portSpeed()));
+        }
+        return Optional.empty();
+    }
+
+    private Set<OchSignal> queryLambdas(DeviceId did, PortNumber port) {
+        try {
+            DriverHandler handler = driverService.createHandler(did);
+            if (handler == null || !handler.hasBehaviour(LambdaQuery.class)) {
+                return Collections.emptySet();
+            }
+            LambdaQuery query = handler.behaviour(LambdaQuery.class);
+            if (query != null) {
+                return query.queryLambdas(port).stream()
+                        .flatMap(x -> OchSignal.toFlexGrid(x).stream())
+                        .collect(Collectors.toSet());
+            } else {
+                return Collections.emptySet();
+            }
+        } catch (ItemNotFoundException e) {
+            return Collections.emptySet();
+        }
+    }
+
+    private Set<VlanId> queryVlanIds(DeviceId device, PortNumber port) {
+        try {
+            DriverHandler handler = driverService.createHandler(device);
+            if (handler == null || !handler.hasBehaviour(VlanQuery.class)) {
+                return ImmutableSet.of();
+            }
+
+            VlanQuery query = handler.behaviour(VlanQuery.class);
+            if (query == null) {
+                return ImmutableSet.of();
+            }
+            return query.queryVlanIds(port);
+        } catch (ItemNotFoundException e) {
+            return ImmutableSet.of();
+        }
+    }
+
+    private Set<MplsLabel> queryMplsLabels(DeviceId device, PortNumber port) {
+        try {
+            DriverHandler handler = driverService.createHandler(device);
+            if (handler == null || !handler.hasBehaviour(MplsQuery.class)) {
+                return ImmutableSet.of();
+            }
+
+            MplsQuery query = handler.behaviour(MplsQuery.class);
+            if (query == null) {
+                return ImmutableSet.of();
+            }
+            return query.queryMplsLabels(port);
+        } catch (ItemNotFoundException e) {
+            return ImmutableSet.of();
+        }
+    }
+
+    private Set<TributarySlot> queryTributarySlots(DeviceId device, PortNumber port) {
+        try {
+            DriverHandler handler = driverService.createHandler(device);
+            if (handler == null || !handler.hasBehaviour(TributarySlotQuery.class)) {
+                return Collections.emptySet();
+            }
+            TributarySlotQuery query = handler.behaviour(TributarySlotQuery.class);
+            if (query != null) {
+                return query.queryTributarySlots(port);
+            } else {
+                return Collections.emptySet();
+            }
+        } catch (ItemNotFoundException e) {
+            return Collections.emptySet();
+        }
+    }
+}
