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 7add217..ffced6c 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
@@ -15,42 +15,68 @@
  */
 package org.onosproject.net.intent.impl.compiler;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
 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.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
 import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
 import org.onosproject.net.flow.DefaultFlowRule;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
 import org.onosproject.net.intent.FlowRuleIntent;
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentCompiler;
 import org.onosproject.net.intent.IntentExtensionService;
 import org.onosproject.net.intent.PathIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.onosproject.net.intent.impl.IntentCompilationException;
+import org.onosproject.net.newresource.ResourcePath;
+import org.onosproject.net.newresource.ResourceService;
 import org.onosproject.net.resource.link.LinkResourceAllocations;
+import org.slf4j.Logger;
 
-import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
 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;
+import static org.slf4j.LoggerFactory.getLogger;
 
 @Component(immediate = true)
 public class PathIntentCompiler implements IntentCompiler<PathIntent> {
 
+    private final Logger log = getLogger(getClass());
+
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected IntentExtensionService intentManager;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ResourceService resourceService;
+
     private ApplicationId appId;
 
     @Activate
@@ -71,29 +97,47 @@
         // TODO: implement recompile behavior
 
         List<Link> links = intent.path().links();
-        List<FlowRule> rules = new ArrayList<>(links.size() - 1);
+        List<FlowRule> rules = new LinkedList<>();
 
-        for (int i = 0; i < links.size() - 1; i++) {
-            ConnectPoint ingress = links.get(i).dst();
-            ConnectPoint egress = links.get(i + 1).src();
-            FlowRule rule = createFlowRule(intent.selector(), intent.treatment(),
-                                           ingress, egress, intent.priority(),
-                                           isLast(links, i));
-            rules.add(rule);
+        Optional<EncapsulationConstraint> enacpConstraint = intent.constraints().stream()
+                .filter(constraint -> constraint instanceof EncapsulationConstraint)
+                .map(x -> (EncapsulationConstraint) x).findAny();
+        //if no encapsulation or is involved only a single switch use the default behaviour
+        if (!enacpConstraint.isPresent() || links.size() == 1) {
+
+            for (int i = 0; i < links.size() - 1; i++) {
+                ConnectPoint ingress = links.get(i).dst();
+                ConnectPoint egress = links.get(i + 1).src();
+                FlowRule rule = createFlowRule(intent.selector(), intent.treatment(),
+                                               ingress, egress, intent.priority(),
+                                               isLast(links, i));
+                rules.add(rule);
+            }
+
+            return ImmutableList.of(new FlowRuleIntent(appId, null, rules, intent.resources()));
+
+        } else {
+            if (EncapsulationType.VLAN == enacpConstraint.get().encapType()) {
+                rules = manageVlanEncap(intent);
+            }
+            if (EncapsulationType.MPLS == enacpConstraint.get().encapType()) {
+                //TODO: to be implemented
+                rules = Collections.emptyList();
+            }
+
+            return ImmutableList.of(new FlowRuleIntent(appId, null, rules, intent.resources()));
         }
-
-        return Collections.singletonList(new FlowRuleIntent(appId, null, rules, intent.resources()));
     }
 
     private FlowRule createFlowRule(TrafficSelector originalSelector, TrafficTreatment originalTreatment,
                                     ConnectPoint ingress, ConnectPoint egress,
-                                    int priority, boolean last) {
+                                    int priority, boolean applyTreatment) {
         TrafficSelector selector = DefaultTrafficSelector.builder(originalSelector)
                 .matchInPort(ingress.port())
                 .build();
 
         TrafficTreatment.Builder treatmentBuilder;
-        if (last) {
+        if (applyTreatment) {
             treatmentBuilder = DefaultTrafficTreatment.builder(originalTreatment);
         } else {
             treatmentBuilder = DefaultTrafficTreatment.builder();
@@ -110,6 +154,138 @@
                 .build();
     }
 
+    private List<FlowRule> manageVlanEncap(PathIntent intent) {
+        Map<LinkKey, VlanId> vlanIds = assignVlanId(intent);
+
+        Iterator<Link> links = intent.path().links().iterator();
+        Link srcLink = links.next();
+
+        Link link = links.next();
+        // List of flow rules to be installed
+        List<FlowRule> rules = new LinkedList<>();
+
+        // Ingress traffic
+        VlanId vlanId = vlanIds.get(linkKey(link));
+        if (vlanId == null) {
+            throw new IntentCompilationException("No available VLAN ID for " + link);
+        }
+        VlanId prevVlanId = vlanId;
+
+        //Tag the traffic with the new VLAN
+        TrafficTreatment treat = DefaultTrafficTreatment.builder()
+                .setVlanId(vlanId)
+                .build();
+
+        rules.add(createFlowRule(intent.selector(), treat, srcLink.dst(), link.src(), intent.priority(), true));
+
+        ConnectPoint prev = link.dst();
+
+        while (links.hasNext()) {
+
+            link = links.next();
+
+            if (links.hasNext()) {
+                // Transit traffic
+                VlanId egressVlanId = vlanIds.get(linkKey(link));
+                if (egressVlanId == null) {
+                    throw new IntentCompilationException("No available VLAN ID for " + link);
+                }
+                prevVlanId = egressVlanId;
+
+                TrafficSelector transitSelector = DefaultTrafficSelector.builder()
+                        .matchInPort(prev.port())
+                        .matchVlanId(prevVlanId).build();
+
+                TrafficTreatment.Builder transitTreat = DefaultTrafficTreatment.builder();
+
+                // Set the new vlanId only if the previous one is different
+                if (!prevVlanId.equals(egressVlanId)) {
+                    transitTreat.setVlanId(egressVlanId);
+                }
+                rules.add(createFlowRule(transitSelector,
+                                         transitTreat.build(), prev, link.src(), intent.priority(), true));
+                prev = link.dst();
+            } else {
+                // Egress traffic
+                TrafficSelector egressSelector = DefaultTrafficSelector.builder()
+                        .matchInPort(prev.port())
+                        .matchVlanId(prevVlanId).build();
+
+                //TODO: think to other cases for egress packet restoration
+                Optional<VlanIdCriterion> vlanCriteria = intent.selector().criteria()
+                        .stream().filter(criteria -> criteria.type() == Criterion.Type.VLAN_VID)
+                        .map(criteria -> (VlanIdCriterion) criteria)
+                        .findAny();
+                TrafficTreatment.Builder egressTreat = DefaultTrafficTreatment.builder(intent.treatment());
+                if (vlanCriteria.isPresent()) {
+                    egressTreat.setVlanId(vlanCriteria.get().vlanId());
+                } else {
+                    egressTreat.popVlan();
+                }
+
+                rules.add(createFlowRule(egressSelector,
+                                         egressTreat.build(), prev, link.src(), intent.priority(), true));
+            }
+
+        }
+        return rules;
+
+    }
+
+    private Map<LinkKey, VlanId> assignVlanId(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(linkRequest);
+        if (vlanIds.isEmpty()) {
+            log.warn("No VLAN IDs available");
+            return Collections.emptyMap();
+        }
+
+        //same VLANID is used for both directions
+        Set<ResourcePath> resources = vlanIds.entrySet().stream()
+                .flatMap(x -> Stream.of(
+                        ResourcePath.discrete(x.getKey().src().deviceId(), x.getKey().src().port(), x.getValue()),
+                        ResourcePath.discrete(x.getKey().dst().deviceId(), x.getKey().dst().port(), x.getValue())
+                ))
+                .collect(Collectors.toSet());
+        List<org.onosproject.net.newresource.ResourceAllocation> allocations =
+                resourceService.allocate(intent.id(), ImmutableList.copyOf(resources));
+        if (allocations.isEmpty()) {
+            Collections.emptyMap();
+        }
+
+        return vlanIds;
+    }
+
+    private Map<LinkKey, VlanId> findVlanIds(Set<LinkKey> links) {
+        Map<LinkKey, VlanId> vlanIds = new HashMap<>();
+        for (LinkKey link : links) {
+            Set<VlanId> forward = findVlanId(link.src());
+            Set<VlanId> backward = findVlanId(link.dst());
+            Set<VlanId> common = Sets.intersection(forward, backward);
+            if (common.isEmpty()) {
+                continue;
+            }
+            vlanIds.put(link, common.iterator().next());
+        }
+        return vlanIds;
+    }
+
+    private Set<VlanId> findVlanId(ConnectPoint cp) {
+        return resourceService.getAvailableResources(ResourcePath.discrete(cp.deviceId(), cp.port())).stream()
+                .filter(x -> x.last() instanceof VlanId)
+                .map(x -> (VlanId) x.last())
+                .collect(Collectors.toSet());
+    }
+
     private boolean isLast(List<Link> links, int i) {
         return i == links.size() - 2;
     }
