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 cad9cb7..045b0ef 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,57 +15,43 @@
  */
 package org.onosproject.net.intent.impl.compiler;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
 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.Link;
-import org.onosproject.net.LinkKey;
+import org.onosproject.net.DeviceId;
 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.flow.instructions.L2ModificationInstruction;
 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.Resource;
 import org.onosproject.net.newresource.ResourceService;
-import org.onosproject.net.newresource.Resources;
 import org.onosproject.net.resource.link.LinkResourceAllocations;
 import org.slf4j.Logger;
 
-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 com.google.common.collect.ImmutableList;
 
-import static org.onosproject.net.LinkKey.linkKey;
 import static org.slf4j.LoggerFactory.getLogger;
 
 @Component(immediate = true)
-public class PathIntentCompiler implements IntentCompiler<PathIntent> {
+public class PathIntentCompiler
+        extends PathCompiler<FlowRule>
+        implements IntentCompiler<PathIntent>,
+                   PathCompiler.PathCompilerCreateFlow<FlowRule> {
 
     private final Logger log = getLogger(getClass());
 
@@ -94,47 +80,30 @@
     @Override
     public List<Intent> compile(PathIntent intent, List<Intent> installable,
                                 Set<LinkResourceAllocations> resources) {
-        // Note: right now recompile is not considered
-        // TODO: implement recompile behavior
 
-        List<Link> links = intent.path().links();
-
-        Optional<EncapsulationConstraint> encapConstraint = 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 (!encapConstraint.isPresent() || 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);
-            }
-
-            return ImmutableList.of(new FlowRuleIntent(appId, null, rules, intent.resources()));
-        }
-
-        List<FlowRule> rules = encapConstraint.map(EncapsulationConstraint::encapType)
-                .map(type -> {
-                    switch (type) {
-                        case VLAN:
-                            return manageVlanEncap(intent);
-                        // TODO: implement MPLS case here
-                        default:
-                            return Collections.<FlowRule>emptyList();
-                    }
-                })
-                .orElse(Collections.emptyList());
+        List<FlowRule> rules = new LinkedList<>();
+        List<DeviceId> devices = new LinkedList<>();
+        compile(this, intent, rules, devices);
 
         return ImmutableList.of(new FlowRuleIntent(appId, null, rules, intent.resources()));
     }
 
-    private FlowRule createFlowRule(TrafficSelector originalSelector, TrafficTreatment originalTreatment,
-                                    ConnectPoint ingress, ConnectPoint egress,
-                                    int priority, boolean applyTreatment) {
+    @Override
+    public Logger log() {
+        return log;
+    }
+
+    @Override
+    public ResourceService resourceService() {
+        return resourceService;
+    }
+
+    @Override
+    public void createFlow(TrafficSelector originalSelector, TrafficTreatment originalTreatment,
+                           ConnectPoint ingress, ConnectPoint egress,
+                           int priority, boolean applyTreatment,
+                           List<FlowRule> rules,
+                           List<DeviceId> devices) {
         TrafficSelector selector = DefaultTrafficSelector.builder(originalSelector)
                 .matchInPort(ingress.port())
                 .build();
@@ -147,164 +116,13 @@
         }
         TrafficTreatment treatment = treatmentBuilder.setOutput(egress.port()).build();
 
-        return DefaultFlowRule.builder()
+        rules.add(DefaultFlowRule.builder()
                 .forDevice(ingress.deviceId())
                 .withSelector(selector)
                 .withTreatment(treatment)
                 .withPriority(priority)
                 .fromApp(appId)
                 .makePermanent()
-                .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;
-
-        Optional<VlanIdCriterion> vlanCriterion = intent.selector().criteria()
-                .stream().filter(criterion -> criterion.type() == Criterion.Type.VLAN_VID)
-                .map(criterion -> (VlanIdCriterion) criterion)
-                .findAny();
-
-        //Push VLAN if selector does not include VLAN
-        TrafficTreatment.Builder treatBuilder = DefaultTrafficTreatment.builder();
-        if (!vlanCriterion.isPresent()) {
-            treatBuilder.pushVlan();
-        }
-        //Tag the traffic with the new encapsulation VLAN
-        treatBuilder.setVlanId(vlanId);
-        rules.add(createFlowRule(intent.selector(), treatBuilder.build(),
-                                 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();
-                TrafficTreatment.Builder egressTreat = DefaultTrafficTreatment.builder(intent.treatment());
-
-                Optional<L2ModificationInstruction.ModVlanIdInstruction> modVlanIdInstruction = intent.treatment()
-                        .allInstructions().stream().filter(
-                                instruction -> instruction instanceof L2ModificationInstruction.ModVlanIdInstruction)
-                        .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x).findAny();
-
-                Optional<L2ModificationInstruction.PopVlanInstruction> popVlanInstruction = intent.treatment()
-                        .allInstructions().stream().filter(
-                                instruction -> instruction instanceof L2ModificationInstruction.PopVlanInstruction)
-                        .map(x -> (L2ModificationInstruction.PopVlanInstruction) x).findAny();
-
-                if (!modVlanIdInstruction.isPresent() && !popVlanInstruction.isPresent()) {
-                    if (vlanCriterion.isPresent()) {
-                        egressTreat.setVlanId(vlanCriterion.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<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<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.getAvailableResourceValues(
-                Resources.discrete(cp.deviceId(), cp.port()).id(),
-                VlanId.class);
-    }
-
-    private boolean isLast(List<Link> links, int i) {
-        return i == links.size() - 2;
+                .build());
     }
 }
