diff --git a/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java b/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
index 6189b6b..436a763 100644
--- a/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
+++ b/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
@@ -36,6 +36,8 @@
 public class MockResourceService implements ResourceService {
 
     private final Map<Resource, ResourceConsumer> assignment = new HashMap<>();
+    public Set<Short> availableVlanLabels = new HashSet<>();
+    public Set<Integer> availableMplsLabels = new HashSet<>();
 
     @Override
     public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<? extends Resource> resources) {
@@ -98,15 +100,45 @@
 
 
     /**
-     * It adds a number of VLAN ids in order to test the random behavior.
+     * Binds VLAN Ids to a parent resource, given a parent resource.
      *
      * @param parent the parent resource
-     * @return a set of VLAN ids
+     * @return the VLAN Ids allocated
      */
     private Collection<Resource> addVlanIds(DiscreteResourceId parent) {
         Collection<Resource> resources = new HashSet<>();
-        for (int i = VlanId.NO_VID + 1; i < VlanId.MAX_VLAN; i++) {
-            resources.add(Resources.discrete(parent).resource().child(VlanId.vlanId((short) i)));
+        if (!this.availableVlanLabels.isEmpty()) {
+            this.availableVlanLabels.forEach(label -> {
+                if (label > VlanId.NO_VID && label < VlanId.MAX_VLAN) {
+                    resources.add(Resources.discrete(parent).resource().child(VlanId.vlanId(label)));
+                }
+            });
+        } else {
+            for (int i = VlanId.NO_VID + 1; i < 1000; i++) {
+                resources.add(Resources.discrete(parent).resource().child(VlanId.vlanId((short) i)));
+            }
+        }
+        return resources;
+    }
+
+    /**
+     * Binds MPLS labels to a parent resource, given a parent resource.
+     *
+     * @param parent the parent resource
+     * @return the MPLS labels allocated
+     */
+    private Collection<Resource> addMplsLabels(DiscreteResourceId parent) {
+        Collection<Resource> resources = new HashSet<>();
+        if (!this.availableMplsLabels.isEmpty()) {
+            this.availableMplsLabels.forEach(label -> {
+                if (label < MplsLabel.MAX_MPLS) {
+                    resources.add(Resources.discrete(parent).resource().child(MplsLabel.mplsLabel(label)));
+                }
+            });
+        } else {
+            for (int i = 1; i < 1000; i++) {
+                resources.add(Resources.discrete(parent).resource().child(MplsLabel.mplsLabel(i)));
+            }
         }
         return resources;
     }
@@ -115,7 +147,7 @@
     public Set<Resource> getAvailableResources(DiscreteResourceId parent) {
         Collection<Resource> resources = new HashSet<>();
         resources.addAll(addVlanIds(parent));
-        resources.add(Resources.discrete(parent).resource().child(MplsLabel.mplsLabel(10)));
+        resources.addAll(addMplsLabels(parent));
         resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(1)));
         resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(2)));
         resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(3)));
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
index fea1e7b..50578de 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
@@ -30,6 +30,7 @@
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentCompiler;
 import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.resource.impl.LabelAllocator;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 
@@ -57,9 +58,15 @@
     private static final boolean DEFAULT_FLOW_OBJECTIVES = false;
     @Property(name = "useFlowObjectives",
             boolValue = DEFAULT_FLOW_OBJECTIVES,
-            label = "Indicates whether to use flow objective-based compilers")
+            label = "Indicates whether or not to use flow objective-based compilers")
     private boolean useFlowObjectives = DEFAULT_FLOW_OBJECTIVES;
 
+    private static final String DEFAULT_LABEL_SELECTION = "RANDOM";
+    @Property(name = "labelSelection",
+            value = DEFAULT_LABEL_SELECTION,
+            label = "Defines the label selection algorithm - RANDOM or FIRST_FIT")
+    private String labelSelection = DEFAULT_LABEL_SELECTION;
+
     private final Map<Class<Intent>, IntentCompiler<Intent>> flowRuleBased = Maps.newConcurrentMap();
     private final Map<Class<Intent>, IntentCompiler<Intent>> flowObjectiveBased = Maps.newConcurrentMap();
 
@@ -79,6 +86,7 @@
     public void modified(ComponentContext context) {
         if (context == null) {
             log.info("Settings: useFlowObjectives={}", useFlowObjectives);
+            log.info("Settings: labelSelection={}", labelSelection);
             return;
         }
 
@@ -95,13 +103,27 @@
             changeCompilers();
             log.info("Settings: useFlowObjectives={}", useFlowObjectives);
         }
+
+        String newLabelSelection;
+        try {
+            String s = Tools.get(context.getProperties(), "labelSelection");
+            newLabelSelection = isNullOrEmpty(s) ? labelSelection : s.trim();
+        } catch (ClassCastException e) {
+            newLabelSelection = labelSelection;
+        }
+
+        if (!labelSelection.equals(newLabelSelection) && LabelAllocator.isInEnum(newLabelSelection)) {
+            labelSelection = newLabelSelection;
+            changeLabelSelections();
+            log.info("Settings: labelSelection={}", labelSelection);
+        }
     }
 
     /**
      * Registers the specified compiler for the given intent class.
      *
-     * @param cls       intent class
-     * @param compiler  intent compiler
+     * @param cls       the intent class
+     * @param compiler  the intent compiler
      * @param flowBased true if the compiler is flow based
      * @param <T>       the type of intent
      */
@@ -121,7 +143,7 @@
     /**
      * Unregisters the compiler for the specified intent class.
      *
-     * @param cls       intent class
+     * @param cls       the intent class
      * @param flowBased true if the compiler is flow based
      * @param <T>       the type of intent
      */
@@ -147,4 +169,8 @@
         }
     }
 
+    private void changeLabelSelections() {
+        PathCompiler.labelAllocator.setLabelSelection(labelSelection);
+    }
+
 }
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathCompiler.java
index b831fef..b236d59 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathCompiler.java
@@ -15,16 +15,15 @@
  */
 package org.onosproject.net.intent.impl.compiler;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
-import org.apache.commons.lang.math.RandomUtils;
 import org.onlab.packet.EthType;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.MplsLabel;
 import org.onlab.packet.VlanId;
+import org.onlab.util.Identifier;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.EncapsulationType;
 import org.onosproject.net.Link;
 import org.onosproject.net.LinkKey;
 import org.onosproject.net.flow.DefaultTrafficSelector;
@@ -40,21 +39,15 @@
 import org.onosproject.net.intent.IntentCompilationException;
 import org.onosproject.net.intent.PathIntent;
 import org.onosproject.net.intent.constraint.EncapsulationConstraint;
-import org.onosproject.net.resource.Resource;
-import org.onosproject.net.resource.ResourceAllocation;
 import org.onosproject.net.resource.ResourceService;
-import org.onosproject.net.resource.Resources;
+import org.onosproject.net.resource.impl.LabelAllocator;
 import org.slf4j.Logger;
 
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 import static org.onosproject.net.LinkKey.linkKey;
 
@@ -64,7 +57,10 @@
 
 public class PathCompiler<T> {
 
-    public static final boolean RANDOM_SELECTION = true;
+    private static final String ERROR_VLAN = "No VLAN Ids available for ";
+    private static final String ERROR_MPLS = "No available MPLS labels for ";
+
+    static LabelAllocator labelAllocator;
 
     /**
      * Defines methods used to create objects representing flows.
@@ -88,108 +84,46 @@
         return i == links.size() - 2;
     }
 
-    private Map<LinkKey, VlanId> assignVlanId(PathCompilerCreateFlow creator, PathIntent intent) {
-        Set<LinkKey> linkRequest =
-                Sets.newHashSetWithExpectedSize(intent.path()
-                        .links().size() - 2);
-        for (int i = 1; i <= intent.path().links().size() - 2; i++) {
-            LinkKey link = linkKey(intent.path().links().get(i));
-            linkRequest.add(link);
-            // add the inverse link. I want that the VLANID is reserved both for
-            // the direct and inverse link
-            linkRequest.add(linkKey(link.dst(), link.src()));
-        }
-
-        Map<LinkKey, VlanId> vlanIds = findVlanIds(creator, linkRequest);
-        if (vlanIds.isEmpty()) {
-            creator.log().warn("No VLAN IDs available");
-            return Collections.emptyMap();
-        }
-
-        //same VLANID is used for both directions
-        Set<Resource> resources = vlanIds.entrySet().stream()
-                .flatMap(x -> Stream.of(
-                        Resources.discrete(x.getKey().src().deviceId(), x.getKey().src().port(), x.getValue())
-                                .resource(),
-                        Resources.discrete(x.getKey().dst().deviceId(), x.getKey().dst().port(), x.getValue())
-                                .resource()
-                ))
-                .collect(Collectors.toSet());
-        List<ResourceAllocation> allocations =
-                creator.resourceService().allocate(intent.id(), ImmutableList.copyOf(resources));
-        if (allocations.isEmpty()) {
-            return Collections.emptyMap();
-        }
-
-        return vlanIds;
-    }
-
     /**
-     * Implements the first fit selection behavior.
+     * Returns the ethertype match needed. If the selector provides
+     * an ethertype, it will be used. IPv4 will be used otherwise.
      *
-     * @param available the set of available VLAN ids.
-     * @return the chosen VLAN id.
+     * @param selector the traffic selector.
+     * @return the ethertype we should match against
      */
-    private VlanId firsFitSelection(Set<VlanId> available) {
-        if (!available.isEmpty()) {
-            return available.iterator().next();
+    private EthType getEthType(TrafficSelector selector) {
+        Criterion c = selector.getCriterion(Criterion.Type.ETH_TYPE);
+        if (c != null && c instanceof EthTypeCriterion) {
+            EthTypeCriterion ethertype = (EthTypeCriterion) c;
+            return ethertype.ethType();
+        } else {
+            return EthType.EtherType.IPV4.ethType();
         }
-        return VlanId.vlanId(VlanId.NO_VID);
     }
 
     /**
-     * Implements the random selection behavior.
+     * Creates the flow rules for the path intent using VLAN
+     * encapsulation.
      *
-     * @param available the set of available VLAN ids.
-     * @return the chosen VLAN id.
+     * @param creator the flowrules creator
+     * @param flows the list of flows to fill
+     * @param devices the devices on the path
+     * @param intent the PathIntent to compile
      */
-    private VlanId randomSelection(Set<VlanId> available) {
-        if (!available.isEmpty()) {
-            int size = available.size();
-            int index = RandomUtils.nextInt(size);
-            return Iterables.get(available, index);
-        }
-        return VlanId.vlanId(VlanId.NO_VID);
-    }
-
-    /**
-    * Select a VLAN id from the set of available VLAN ids.
-    *
-    * @param available the set of available VLAN ids.
-    * @return the chosen VLAN id.
-    */
-    private VlanId selectVlanId(Set<VlanId> available) {
-        return RANDOM_SELECTION ? randomSelection(available) : firsFitSelection(available);
-    }
-
-    private Map<LinkKey, VlanId> findVlanIds(PathCompilerCreateFlow creator, Set<LinkKey> links) {
-        Map<LinkKey, VlanId> vlanIds = new HashMap<>();
-        for (LinkKey link : links) {
-            Set<VlanId> forward = findVlanId(creator, link.src());
-            Set<VlanId> backward = findVlanId(creator, link.dst());
-            Set<VlanId> common = Sets.intersection(forward, backward);
-            if (common.isEmpty()) {
-                continue;
-            }
-            VlanId selected = selectVlanId(common);
-            if (selected.toShort() == VlanId.NO_VID) {
-                continue;
-            }
-            vlanIds.put(link, selected);
-        }
-        return vlanIds;
-    }
-
-    private Set<VlanId> findVlanId(PathCompilerCreateFlow creator, ConnectPoint cp) {
-        return creator.resourceService().getAvailableResourceValues(
-                Resources.discrete(cp.deviceId(), cp.port()).id(),
-                VlanId.class);
-    }
-
     private void manageVlanEncap(PathCompilerCreateFlow<T> creator, List<T> flows,
                                  List<DeviceId> devices,
                                  PathIntent intent) {
-        Map<LinkKey, VlanId> vlanIds = assignVlanId(creator, intent);
+
+        Set<Link> linksSet = Sets.newConcurrentHashSet();
+        for (int i = 1; i <= intent.path().links().size() - 2; i++) {
+            linksSet.add(intent.path().links().get(i));
+        }
+
+        Map<LinkKey, Identifier<?>> vlanIds = labelAllocator.assignLabelToLinks(
+                linksSet,
+                intent.id(),
+                EncapsulationType.VLAN
+        );
 
         Iterator<Link> links = intent.path().links().iterator();
         Link srcLink = links.next();
@@ -197,9 +131,9 @@
         Link link = links.next();
 
         // Ingress traffic
-        VlanId vlanId = vlanIds.get(linkKey(link));
+        VlanId vlanId = (VlanId) vlanIds.get(linkKey(link));
         if (vlanId == null) {
-            throw new IntentCompilationException("No available VLAN ID for " + link);
+            throw new IntentCompilationException(ERROR_VLAN + link);
         }
         VlanId prevVlanId = vlanId;
 
@@ -227,9 +161,9 @@
 
             if (links.hasNext()) {
                 // Transit traffic
-                VlanId egressVlanId = vlanIds.get(linkKey(link));
+                VlanId egressVlanId = (VlanId) vlanIds.get(linkKey(link));
                 if (egressVlanId == null) {
-                    throw new IntentCompilationException("No available VLAN ID for " + link);
+                    throw new IntentCompilationException(ERROR_VLAN + link);
                 }
 
                 TrafficSelector transitSelector = DefaultTrafficSelector.builder()
@@ -284,68 +218,29 @@
         }
     }
 
-    private Map<LinkKey, MplsLabel> assignMplsLabel(PathCompilerCreateFlow creator, PathIntent intent) {
-                Set<LinkKey> linkRequest =
-                Sets.newHashSetWithExpectedSize(intent.path()
-                        .links().size() - 2);
-        for (int i = 1; i <= intent.path().links().size() - 2; i++) {
-            LinkKey link = linkKey(intent.path().links().get(i));
-            linkRequest.add(link);
-            // add the inverse link. I want that the VLANID is reserved both for
-            // the direct and inverse link
-            linkRequest.add(linkKey(link.dst(), link.src()));
-        }
-
-        Map<LinkKey, MplsLabel> labels = findMplsLabels(creator, linkRequest);
-        if (labels.isEmpty()) {
-            throw new IntentCompilationException("No available MPLS Label");
-        }
-
-        // for short term solution: same label is used for both directions
-        // TODO: introduce the concept of Tx and Rx resources of a port
-        Set<Resource> resources = labels.entrySet().stream()
-                .flatMap(x -> Stream.of(
-                        Resources.discrete(x.getKey().src().deviceId(), x.getKey().src().port(), x.getValue())
-                                .resource(),
-                        Resources.discrete(x.getKey().dst().deviceId(), x.getKey().dst().port(), x.getValue())
-                                .resource()
-                ))
-                .collect(Collectors.toSet());
-        List<ResourceAllocation> allocations =
-                creator.resourceService().allocate(intent.id(), ImmutableList.copyOf(resources));
-        if (allocations.isEmpty()) {
-            return Collections.emptyMap();
-        }
-
-        return labels;
-    }
-
-    private Map<LinkKey, MplsLabel> findMplsLabels(PathCompilerCreateFlow creator, Set<LinkKey> links) {
-        Map<LinkKey, MplsLabel> labels = new HashMap<>();
-        for (LinkKey link : links) {
-            Set<MplsLabel> forward = findMplsLabel(creator, link.src());
-            Set<MplsLabel> backward = findMplsLabel(creator, link.dst());
-            Set<MplsLabel> common = Sets.intersection(forward, backward);
-            if (common.isEmpty()) {
-                continue;
-            }
-            labels.put(link, common.iterator().next());
-        }
-
-        return labels;
-    }
-
-    private Set<MplsLabel> findMplsLabel(PathCompilerCreateFlow creator, ConnectPoint cp) {
-        return creator.resourceService().getAvailableResourceValues(
-                Resources.discrete(cp.deviceId(), cp.port()).id(),
-                MplsLabel.class);
-    }
-
+    /**
+     * Creates the flow rules for the path intent using MPLS
+     * encapsulation.
+     *
+     * @param creator the flowrules creator
+     * @param flows the list of flows to fill
+     * @param devices the devices on the path
+     * @param intent the PathIntent to compile
+     */
     private void manageMplsEncap(PathCompilerCreateFlow<T> creator, List<T> flows,
                                            List<DeviceId> devices,
                                            PathIntent intent) {
-        Map<LinkKey, MplsLabel> mplsLabels = assignMplsLabel(creator, intent);
 
+        Set<Link> linksSet = Sets.newConcurrentHashSet();
+        for (int i = 1; i <= intent.path().links().size() - 2; i++) {
+            linksSet.add(intent.path().links().get(i));
+        }
+
+        Map<LinkKey, Identifier<?>> mplsLabels = labelAllocator.assignLabelToLinks(
+                linksSet,
+                intent.id(),
+                EncapsulationType.MPLS
+        );
         Iterator<Link> links = intent.path().links().iterator();
         Link srcLink = links.next();
 
@@ -353,9 +248,9 @@
         // List of flow rules to be installed
 
         // Ingress traffic
-        MplsLabel mplsLabel = mplsLabels.get(linkKey(link));
+        MplsLabel mplsLabel = (MplsLabel) mplsLabels.get(linkKey(link));
         if (mplsLabel == null) {
-            throw new IntentCompilationException("No available MPLS Label for " + link);
+            throw new IntentCompilationException(ERROR_MPLS + link);
         }
         MplsLabel prevMplsLabel = mplsLabel;
 
@@ -382,12 +277,10 @@
 
             if (links.hasNext()) {
                 // Transit traffic
-                MplsLabel transitMplsLabel = mplsLabels.get(linkKey(link));
+                MplsLabel transitMplsLabel = (MplsLabel) mplsLabels.get(linkKey(link));
                 if (transitMplsLabel == null) {
-                    throw new IntentCompilationException("No available MPLS label for " + link);
+                    throw new IntentCompilationException(ERROR_MPLS + link);
                 }
-                prevMplsLabel = transitMplsLabel;
-
                 TrafficSelector transitSelector = DefaultTrafficSelector.builder()
                         .matchInPort(prev.port())
                         .matchEthType(Ethernet.MPLS_UNICAST)
@@ -395,12 +288,13 @@
 
                 TrafficTreatment.Builder transitTreat = DefaultTrafficTreatment.builder();
 
-                // Set the new MPLS Label only if the previous one is different
+                // Set the new MPLS label only if the previous one is different
                 if (!prevMplsLabel.equals(transitMplsLabel)) {
                     transitTreat.setMpls(transitMplsLabel);
                 }
                 creator.createFlow(transitSelector,
                         transitTreat.build(), prev, link.src(), intent.priority(), true, flows, devices);
+                prevMplsLabel = transitMplsLabel;
                 prev = link.dst();
             } else {
                 TrafficSelector.Builder egressSelector = DefaultTrafficSelector.builder()
@@ -428,14 +322,7 @@
                 if (mplsCriterion.isPresent()) {
                     egressTreat.setMpls(mplsCriterion.get().label());
                 } else {
-                    egressTreat.popMpls(outputEthType(intent.selector()));
-                }
-
-
-                if (mplsCriterion.isPresent()) {
-                    egressTreat.setMpls(mplsCriterion.get().label());
-                } else {
-                    egressTreat.popVlan();
+                    egressTreat.popMpls(getEthType(intent.selector()));
                 }
 
                 creator.createFlow(egressSelector.build(),
@@ -446,23 +333,6 @@
 
     }
 
-    private MplsLabel getMplsLabel(Map<LinkKey, MplsLabel> labels, LinkKey link) {
-        return labels.get(link);
-    }
-
-    // if the ingress ethertype is defined, the egress traffic
-    // will be use that value, otherwise the IPv4 ethertype is used.
-    private EthType outputEthType(TrafficSelector selector) {
-        Criterion c = selector.getCriterion(Criterion.Type.ETH_TYPE);
-        if (c != null && c instanceof EthTypeCriterion) {
-            EthTypeCriterion ethertype = (EthTypeCriterion) c;
-            return ethertype.ethType();
-        } else {
-            return EthType.EtherType.IPV4.ethType();
-        }
-    }
-
-
     /**
      * Compiles an intent down to flows.
      *
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentCompiler.java
index fdcdd00..ddc7f21 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentCompiler.java
@@ -36,6 +36,7 @@
 import org.onosproject.net.intent.IntentCompiler;
 import org.onosproject.net.intent.PathIntent;
 import org.onosproject.net.resource.ResourceService;
+import org.onosproject.net.resource.impl.LabelAllocator;
 import org.slf4j.Logger;
 
 import java.util.LinkedList;
@@ -67,6 +68,7 @@
     public void activate() {
         appId = coreService.registerApplication("org.onosproject.net.intent");
         registrator.registerCompiler(PathIntent.class, this, false);
+        labelAllocator = new LabelAllocator(resourceService);
     }
 
     @Deactivate
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentFlowObjectiveCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentFlowObjectiveCompiler.java
index ac1c051..3f0fc19 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentFlowObjectiveCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentFlowObjectiveCompiler.java
@@ -40,6 +40,7 @@
 import org.onosproject.net.intent.IntentCompiler;
 import org.onosproject.net.intent.PathIntent;
 import org.onosproject.net.resource.ResourceService;
+import org.onosproject.net.resource.impl.LabelAllocator;
 import org.slf4j.Logger;
 
 import java.util.LinkedList;
@@ -73,6 +74,7 @@
     public void activate() {
         appId = coreService.registerApplication("org.onosproject.net.intent");
         registrator.registerCompiler(PathIntent.class, this, true);
+        labelAllocator = new LabelAllocator(resourceService);
     }
 
     @Deactivate
diff --git a/core/net/src/main/java/org/onosproject/net/resource/impl/LabelAllocator.java b/core/net/src/main/java/org/onosproject/net/resource/impl/LabelAllocator.java
new file mode 100644
index 0000000..4086768
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/resource/impl/LabelAllocator.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2016-present 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.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.apache.commons.lang.math.RandomUtils;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onlab.util.Identifier;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
+import org.onosproject.net.intent.IntentId;
+import org.onosproject.net.resource.Resource;
+import org.onosproject.net.resource.ResourceAllocation;
+import org.onosproject.net.resource.ResourceService;
+import org.onosproject.net.resource.Resources;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Helper class which interacts with the ResourceService and provides
+ * a unified API to allocate MPLS labels and VLAN Ids.
+ */
+public final class LabelAllocator {
+
+    private enum Behavior {
+        /**
+         * Random selection.
+         */
+        RANDOM,
+        /**
+         * First fit selection.
+         */
+        FIRST_FIT
+    }
+
+    private static final Behavior[] BEHAVIORS = Behavior.values();
+
+    private ResourceService resourceService;
+    private LabelSelection labelSelection;
+
+    /**
+     * Creates a new label allocator. Random is the
+     * default behavior.
+     *
+     * @param rs the resource service
+     */
+    public LabelAllocator(ResourceService rs) {
+        this.resourceService = rs;
+        this.labelSelection = this.getLabelSelection(Behavior.RANDOM);
+    }
+
+    /**
+     * Checks if a given string is a valid Behavior.
+     *
+     * @param value the string to check
+     * @return true if value is a valid Behavior, false otherwise
+     */
+    public static boolean isInEnum(String value) {
+        for (Behavior b : BEHAVIORS) {
+            if (b.name().equals(value)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Changes the selection behavior.
+     *
+     * @param type the behavior type
+     */
+    public void setLabelSelection(String type) {
+        if (isInEnum(type)) {
+            this.labelSelection = this.getLabelSelection(type);
+        }
+    }
+
+    /**
+     * Retrieves the label selection behavior.
+     *
+     * @return the label selection behavior in use
+     */
+    public LabelSelection getLabelSelection() {
+        return this.labelSelection;
+    }
+
+    /**
+     * Returns the label selection behavior, given a behavior type.
+     *
+     * @param type the behavior type
+     * @return the label selection behavior in use
+     */
+    private LabelSelection getLabelSelection(String type) {
+        Behavior behavior = Behavior.valueOf(type);
+        return this.getLabelSelection(behavior);
+    }
+
+    /**
+     * Creates a new LabelSelection. Random is
+     * the default label selection behavior.
+     *
+     * @param type the behavior type
+     * @return the object implementing the behavior
+     */
+    private LabelSelection getLabelSelection(Behavior type) {
+        LabelSelection selection = null;
+        switch (type) {
+            case FIRST_FIT:
+                selection = new FirstFitSelection();
+                break;
+            case RANDOM:
+            default:
+                selection = new RandomSelection();
+                break;
+        }
+        return selection;
+    }
+
+    /**
+     * Looks for available Ids.
+     *
+     * @param links the links where to look for Ids
+     * @param  type the encapsulation type
+     * @return the mappings between key and id
+     */
+    private Map<LinkKey, Identifier<?>> findAvailableIDs(Set<LinkKey> links, EncapsulationType type) {
+
+        Map<LinkKey, Identifier<?>> ids = Maps.newHashMap();
+        for (LinkKey link : links) {
+            Set<Identifier<?>> availableIDsatSrc = getAvailableIDs(link.src(), type);
+            Set<Identifier<?>> availableIDsatDst = getAvailableIDs(link.dst(), type);
+            Set<Identifier<?>> common = Sets.intersection(availableIDsatSrc, availableIDsatDst);
+            if (common.isEmpty()) {
+                continue;
+            }
+            Identifier<?> selected = labelSelection.select(common);
+            if (selected == null) {
+                continue;
+            }
+            ids.put(link, selected);
+        }
+        return ids;
+    }
+
+    /**
+     * Looks for available Ids associated to the given connection point.
+     *
+     * @param cp the connection point
+     * @param type the type of Id
+     * @return the set of available Ids
+     */
+    private Set<Identifier<?>> getAvailableIDs(ConnectPoint cp, EncapsulationType type) {
+        return resourceService.getAvailableResourceValues(
+                Resources.discrete(cp.deviceId(), cp.port()).id(), getEncapsulationClass(type)
+        );
+    }
+
+    /**
+     * Method to map the encapsulation type to identifier class.
+     * VLAN is the default encapsulation.
+     *
+     * @param type the type of encapsulation
+     * @return the id class
+     */
+    private Class getEncapsulationClass(EncapsulationType type) {
+        Class idType;
+        switch (type) {
+            case MPLS:
+                idType = MplsLabel.class;
+                break;
+            case VLAN:
+            default:
+                idType = VlanId.class;
+        }
+        return idType;
+    }
+
+    /**
+     * Allocates labels and associates them to links.
+     *
+     * @param links the links where labels will be allocated
+     * @param id the intent Id
+     * @param type the encapsulation type
+     * @return the list of links and associated labels
+     */
+    public Map<LinkKey, Identifier<?>> assignLabelToLinks(Set<Link> links, IntentId id, EncapsulationType type) {
+
+        Set<LinkKey> linkRequest = Sets.newHashSet();
+
+        links.forEach(link -> {
+            linkRequest.add(LinkKey.linkKey(link));
+        });
+
+        Map<LinkKey, Identifier<?>> availableIds = findAvailableIDs(linkRequest, type);
+        if (availableIds.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        Set<Resource> resources = availableIds.entrySet().stream()
+                .flatMap(x -> Stream.of(
+                        Resources.discrete(
+                                x.getKey().src().deviceId(),
+                                x.getKey().src().port(),
+                                x.getValue()
+                        ).resource(),
+                        Resources.discrete(
+                                x.getKey().dst().deviceId(),
+                                x.getKey().dst().port(),
+                                x.getValue()
+                        ).resource()
+                ))
+                .collect(Collectors.toSet());
+
+        List<ResourceAllocation> allocations = resourceService.allocate(id, ImmutableList.copyOf(resources));
+
+        if (allocations.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        return ImmutableMap.copyOf(availableIds);
+    }
+
+    /**
+     * Allocates labels and associates them to source
+     * and destination ports of a link.
+     *
+     * @param links the links on which labels will be reserved
+     * @param id the intent Id
+     * @param type the encapsulation type
+     * @return the list of ports and associated labels
+     */
+    public Map<ConnectPoint, Identifier<?>> assignLabelToPorts(Set<Link> links, IntentId id, EncapsulationType type) {
+        Map<LinkKey, Identifier<?>> allocation = this.assignLabelToLinks(links, id, type);
+        if (allocation.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        Map<ConnectPoint, Identifier<?>> finalAllocation = Maps.newHashMap();
+        allocation.forEach((key, value) -> {
+            finalAllocation.putIfAbsent(key.src(), value);
+            finalAllocation.putIfAbsent(key.dst(), value);
+        });
+        return ImmutableMap.copyOf(finalAllocation);
+    }
+
+    /**
+     * Interface for selection algorithms of the labels.
+     */
+    public interface LabelSelection {
+
+        /**
+         * Picks an element from values using a particular algorithm.
+         *
+         * @param values the values to select from
+         * @return the selected identifier if values are present, null otherwise
+         */
+        Identifier<?> select(Set<Identifier<?>> values);
+
+    }
+
+    /**
+     * Random label selection.
+     */
+    public static class RandomSelection implements LabelSelection {
+
+        /**
+         * Selects an identifier from a given set of values using
+         * the random selection algorithm.
+         *
+         * @param values the values to select from
+         * @return the selected identifier if values are present, null otherwise
+         */
+        @Override
+        public Identifier<?> select(Set<Identifier<?>> values) {
+            if (!values.isEmpty()) {
+                int size = values.size();
+                int index = RandomUtils.nextInt(size);
+                return Iterables.get(values, index);
+            }
+            return null;
+        }
+    }
+
+    /**
+     * First fit label selection.
+     */
+    public static class FirstFitSelection implements LabelSelection {
+
+        /**
+         * Selects an identifier from a given set of values using
+         * the first fir selection algorithm.
+         *
+         * @param values the values to select from
+         * @return the selected identifier if values are present, null otherwise.
+         */
+        @Override
+        public Identifier<?> select(Set<Identifier<?>> values) {
+            if (!values.isEmpty()) {
+                return values.iterator().next();
+            }
+            return null;
+        }
+    }
+
+}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PathIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PathIntentCompilerTest.java
index a636fd4..e9f5170 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PathIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PathIntentCompilerTest.java
@@ -163,7 +163,8 @@
     private PathIntent constraintMplsIntent;
 
     /**
-     * Configures objects used in all the test cases.
+     * Configures mock objects used in all the test cases.
+     * Creates the intents to test as well.
      */
     @Before
     public void setUp() {
@@ -914,14 +915,12 @@
     }
 
     /**
-     * Tests the random selection of VlanIds in the PathCompiler.
+     * Tests the random selection of VLAN Ids in the PathCompiler.
      * It can fail randomly (it is unlikely)
      */
     @Test
     public void testRandomVlanSelection() {
 
-        if (PathCompiler.RANDOM_SELECTION) {
-
             sut.activate();
 
             List<Intent> compiled = sut.compile(constraintVlanIntent, Collections.emptyList());
@@ -969,7 +968,6 @@
 
             sut.deactivate();
 
-        }
 
     }
 
@@ -1043,8 +1041,10 @@
                 .findFirst()
                 .get();
         verifyIdAndPriority(rule1, d1p0.deviceId());
-        assertThat(rule1.selector(), is(DefaultTrafficSelector.builder(selector)
-                .matchInPort(d1p0.port()).build()));
+        assertThat(rule1.selector(), is(DefaultTrafficSelector
+                                                .builder(selector)
+                                                .matchInPort(d1p0.port())
+                                                .build()));
         MplsLabel mplsLabelToEncap = verifyMplsEncapTreatment(rule1.treatment(), d1p1, true, false);
 
         FlowRule rule2 = rules.stream()
@@ -1053,7 +1053,7 @@
                 .get();
         verifyIdAndPriority(rule2, d2p0.deviceId());
         verifyMplsEncapSelector(rule2.selector(), d2p0, mplsLabelToEncap);
-        verifyMplsEncapTreatment(rule2.treatment(), d2p1, false, false);
+        mplsLabelToEncap = verifyMplsEncapTreatment(rule2.treatment(), d2p1, false, false);
 
         FlowRule rule3 = rules.stream()
                 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
@@ -1077,19 +1077,29 @@
         assertThat((ruleOutput.iterator().next()).port(), is(egress.port()));
         MplsLabel mplsToEncap = MplsLabel.mplsLabel(0);
         if (isIngress && !isEgress) {
-            Set<L2ModificationInstruction.ModMplsLabelInstruction> mplsRules =
-                    trafficTreatment.allInstructions().stream()
-                            .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
-                            .map(x -> (L2ModificationInstruction.ModMplsLabelInstruction) x)
-                            .collect(Collectors.toSet());
+            Set<L2ModificationInstruction.ModMplsLabelInstruction> mplsRules = trafficTreatment
+                    .allInstructions()
+                    .stream()
+                    .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
+                    .map(x -> (L2ModificationInstruction.ModMplsLabelInstruction) x)
+                    .collect(Collectors.toSet());
             assertThat(mplsRules, hasSize(1));
             L2ModificationInstruction.ModMplsLabelInstruction mplsRule = mplsRules.iterator().next();
-            assertThat(mplsRule.mplsLabel().toInt(), greaterThan(0));
-            mplsToEncap = mplsRule.mplsLabel();
+            assertThat(mplsRule.label().toInt(), greaterThan(0));
+            assertThat(mplsRule.label().toInt(), lessThan(MplsLabel.MAX_MPLS));
+            mplsToEncap = mplsRule.label();
         } else if (!isIngress && !isEgress) {
-            assertThat(trafficTreatment.allInstructions().stream()
-                               .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
-                               .collect(Collectors.toSet()), hasSize(0));
+            Set<L2ModificationInstruction.ModMplsLabelInstruction> mplsRules = trafficTreatment
+                    .allInstructions()
+                    .stream()
+                    .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
+                    .map(x -> (L2ModificationInstruction.ModMplsLabelInstruction) x)
+                    .collect(Collectors.toSet());
+            assertThat(mplsRules, hasSize(1));
+            L2ModificationInstruction.ModMplsLabelInstruction mplsRule = mplsRules.iterator().next();
+            assertThat(mplsRule.label().toInt(), greaterThan(0));
+            assertThat(mplsRule.label().toInt(), lessThan(MplsLabel.MAX_MPLS));
+            mplsToEncap = mplsRule.label();
         } else {
             assertThat(trafficTreatment.allInstructions().stream()
                                .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
@@ -1099,7 +1109,6 @@
                                .collect(Collectors.toSet()), hasSize(1));
 
         }
-
         return mplsToEncap;
 
     }
diff --git a/core/net/src/test/java/org/onosproject/net/resource/impl/LabelAllocatorTest.java b/core/net/src/test/java/org/onosproject/net/resource/impl/LabelAllocatorTest.java
new file mode 100644
index 0000000..4c47735
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/resource/impl/LabelAllocatorTest.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2016-present 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 org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onlab.util.Identifier;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
+import org.onosproject.net.intent.IntentId;
+import org.onosproject.net.intent.MockIdGenerator;
+import org.onosproject.net.resource.MockResourceService;
+import org.onosproject.net.resource.impl.LabelAllocator.FirstFitSelection;
+import org.onosproject.net.resource.impl.LabelAllocator.LabelSelection;
+import org.onosproject.net.resource.impl.LabelAllocator.RandomSelection;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
+import static org.onosproject.net.Link.Type.DIRECT;
+import static org.onosproject.net.NetTestTools.PID;
+import static org.onosproject.net.NetTestTools.connectPoint;
+
+/**
+ * Unit tests for LabelAllocator.
+ */
+public class LabelAllocatorTest {
+
+    private LabelAllocator allocator;
+    private MockResourceService resourceService;
+    private IdGenerator idGenerator = new MockIdGenerator();
+
+    private final ConnectPoint d1p0 = connectPoint("s1", 0);
+    private final ConnectPoint d1p1 = connectPoint("s1", 1);
+    private final ConnectPoint d2p0 = connectPoint("s2", 0);
+    private final ConnectPoint d2p1 = connectPoint("s2", 1);
+
+    private final List<Link> links = Arrays.asList(
+            createEdgeLink(d1p0, true),
+            DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p1).type(DIRECT).build(),
+            createEdgeLink(d2p0, false)
+    );
+
+    private final String firstFit = "FIRST_FIT";
+    private final String random = "RANDOM";
+    private final String wrong = "BLAHBLAHBLAH";
+
+    @Before
+    public void setUp() {
+        this.resourceService = new MockResourceService();
+        this.allocator = new LabelAllocator(this.resourceService);
+    }
+
+    @After
+    public void tearDown() {
+
+    }
+
+    /**
+     * To test changes to the selection behavior.
+     */
+    @Test
+    public void testChangeBehavior() {
+        // It has to be an instance of LabelSelection
+        assertThat(this.allocator.getLabelSelection(), instanceOf(LabelSelection.class));
+        // By default we have Random Selection
+        assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+        // We change to FirstFit and we test the change
+        this.allocator.setLabelSelection(firstFit);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+        // We change to Random and we test the change
+        this.allocator.setLabelSelection(random);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+        // We put a wrong type and we should have a Random selection
+        this.allocator.setLabelSelection(wrong);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+    }
+
+    /**
+     * To test the first fit behavior with VLAN Id. In the First step
+     * we use the default set, for the first selection the selected label
+     * has to be 1. In the Second step we change the default set and for
+     * the first fit selection the selected has to be 2.
+     */
+    @Test
+    public void testFirstFitBehaviorVlan() {
+        // We change to FirstFit and we test the change
+        this.allocator.setLabelSelection(firstFit);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+        // We test the behavior for VLAN
+        Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 2)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
+        // value has to be a VlanId
+        assertThat(id, instanceOf(VlanId.class));
+        // value should not be a forbidden value
+        VlanId vlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+        // value will be always 1
+        assertEquals(1, vlanId.toShort());
+
+        // We change the available Ids
+        this.resourceService.availableVlanLabels = ImmutableSet.of(
+                (short) 100,
+                (short) 11,
+                (short) 20,
+                (short) 2,
+                (short) 3
+        );
+        // We test again the behavior for VLAN
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 2)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
+        // value has to be a VlanId
+        assertThat(id, instanceOf(VlanId.class));
+        // value should not be a forbidden value
+        vlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+        // value will be always 2
+        assertEquals(2, vlanId.toShort());
+    }
+
+    /**
+     * To test the first fit behavior with MPLS label. In the First step
+     * we use the default set, for the first selection the selected label
+     * has to be 1. In the Second step we change the default set and for
+     * the first fit selection the selected has to be 100.
+     */
+    @Test
+    public void testFirstFitBehaviorMpls() {
+        // We change to FirstFit and we test the change
+        this.allocator.setLabelSelection(firstFit);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+        // We test the behavior for MPLS
+        Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 2)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.MPLS);
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
+        // value has to be a Mplslabel
+        assertThat(id, instanceOf(MplsLabel.class));
+        // value should not be a forbidden value
+        MplsLabel mplsLabel = (MplsLabel) id;
+        assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+        // value will be always 1
+        assertEquals(1, mplsLabel.toInt());
+
+        // We change the available Ids
+        this.resourceService.availableMplsLabels = ImmutableSet.of(
+                100,
+                200,
+                1000
+        );
+        // We test again the behavior for MPLS
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 2)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.MPLS);
+        id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
+        // value has to be a Mplslabel
+        assertThat(id, instanceOf(MplsLabel.class));
+        // value should not be a forbidden value
+        mplsLabel = (MplsLabel) id;
+        assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+        // value will be always 100
+        assertEquals(100, mplsLabel.toInt());
+    }
+
+    /**
+     * To test the random behavior with VLAN Id. We make two selection,
+     * we test that these two selection are different.
+     */
+    @Test
+    public void testRandomBehaviorVlan() {
+        // Verify the random behavior
+        assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+        // We test the behavior for VLAN
+        Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 2)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
+        // value has to be a VlanId
+        assertThat(id, instanceOf(VlanId.class));
+        // value should not be a forbidden value
+        Short value = Short.parseShort(id.toString());
+        VlanId prevVlanId = VlanId.vlanId(value);
+        assertTrue(VlanId.NO_VID < prevVlanId.toShort() && prevVlanId.toShort() < VlanId.MAX_VLAN);
+
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 2)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+         id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
+        // value has to be a VlanId
+        assertThat(id, instanceOf(VlanId.class));
+        // value should not be a forbidden value
+        VlanId vlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+        assertNotEquals(vlanId, prevVlanId);
+
+    }
+
+    /**
+     * To test random behavior with MPLS label. We make two selection,
+     * we test that these two selection are different.
+     */
+    @Test
+    public void testRandomBehaviorMpls() {
+        // Verify the random behavior
+        assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+        // We test the behavior for MPLS
+        Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 2)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.MPLS);
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
+        // value has to be a Mplslabel
+        assertThat(id, instanceOf(MplsLabel.class));
+        // value should not be a forbidden value
+        MplsLabel prevMplsId = (MplsLabel) id;
+        assertTrue(0 < prevMplsId.toInt() && prevMplsId.toInt() < MplsLabel.MAX_MPLS);
+
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 2)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.MPLS);
+        id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
+        // value has to be a Mplslabel
+        assertThat(id, instanceOf(MplsLabel.class));
+        // value should not be a forbidden value
+        MplsLabel mplsId = (MplsLabel) id;
+        assertTrue(0 < mplsId.toInt() && mplsId.toInt() < MplsLabel.MAX_MPLS);
+        assertNotEquals(prevMplsId, mplsId);
+
+    }
+
+    /**
+     * To test the port key based API.
+     */
+    @Test
+    public void testPortKey() {
+        // Verify the first behavior
+        this.allocator.setLabelSelection(firstFit);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+        // We test the behavior for VLAN
+        Map<ConnectPoint, Identifier<?>> allocation = this.allocator.assignLabelToPorts(
+                ImmutableSet.copyOf(links.subList(1, 2)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        Identifier<?> id = allocation.get(new ConnectPoint(d1p1.elementId(), d1p1.port()));
+        // value has to be a VlanId
+        assertThat(id, instanceOf(VlanId.class));
+        // value should not be a forbidden value
+        VlanId prevVlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < prevVlanId.toShort() && prevVlanId.toShort() < VlanId.MAX_VLAN);
+        // value has to be 1
+        assertEquals(1, prevVlanId.toShort());
+        // verify same applies for d2p1
+        id = allocation.get(new ConnectPoint(d2p1.elementId(), d2p1.port()));
+        assertThat(id, instanceOf(VlanId.class));
+        // value should not be a forbidden value
+        VlanId vlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+        // value has to be 1
+        assertEquals(prevVlanId, vlanId);
+    }
+
+
+
+}
diff --git a/utils/misc/src/main/java/org/onlab/packet/MplsLabel.java b/utils/misc/src/main/java/org/onlab/packet/MplsLabel.java
index 82f951f..6a1418d 100644
--- a/utils/misc/src/main/java/org/onlab/packet/MplsLabel.java
+++ b/utils/misc/src/main/java/org/onlab/packet/MplsLabel.java
@@ -15,18 +15,18 @@
  */
 package org.onlab.packet;
 
+import org.onlab.util.Identifier;
+
 /**
  * Representation of a MPLS label.
  */
-public class MplsLabel {
-
-    private final int mplsLabel;
+public final class MplsLabel extends Identifier<Integer> {
 
     // An MPLS Label maximum 20 bits.
     public static final int MAX_MPLS = 0xFFFFF;
 
     protected MplsLabel(int value) {
-        this.mplsLabel = value;
+        super(value);
     }
 
     public static MplsLabel mplsLabel(int value) {
@@ -39,35 +39,27 @@
         return new MplsLabel(value);
     }
 
+    /**
+     * Creates a MplsLabel object using the supplied decimal string.
+     *
+     * @param value the MPLS identifier expressed as string
+     * @return Mplslabel object created from the string
+     */
+    public static MplsLabel mplsLabel(String value) {
+        try {
+            return MplsLabel.mplsLabel(Integer.parseInt(value));
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
     public int toInt() {
-        return this.mplsLabel;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-
-        if (obj instanceof MplsLabel) {
-
-            MplsLabel other = (MplsLabel) obj;
-
-            if (this.mplsLabel == other.mplsLabel) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return this.mplsLabel;
+        return this.id();
     }
 
     @Override
     public String toString() {
-        return String.valueOf(this.mplsLabel);
+        return String.valueOf(this.identifier);
     }
+
 }
