diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ProtectedTransportIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ProtectedTransportIntentCompiler.java
new file mode 100644
index 0000000..52c6dee
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ProtectedTransportIntentCompiler.java
@@ -0,0 +1,463 @@
+/*
+ * 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.intent.impl.compiler;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.Lists.transform;
+import static java.util.stream.Stream.concat;
+import static org.onosproject.net.behaviour.protection.ProtectedTransportEndpointDescription.buildDescription;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.commons.lang3.RandomUtils;
+import org.apache.commons.lang3.tuple.Pair;
+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.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DefaultPath;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Link;
+import org.onosproject.net.Link.State;
+import org.onosproject.net.NetworkResource;
+import org.onosproject.net.Path;
+import org.onosproject.net.behaviour.protection.TransportEndpointDescription;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentCompilationException;
+import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.intent.ProtectedTransportIntent;
+import org.onosproject.net.intent.ProtectionEndpointIntent;
+import org.onosproject.net.resource.DiscreteResourceId;
+import org.onosproject.net.resource.Resource;
+import org.onosproject.net.resource.ResourceService;
+import org.onosproject.net.resource.Resources;
+import org.slf4j.Logger;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * IntentCompiler for {@link ProtectedTransportIntent}.
+ */
+@Beta
+@Component(immediate = true)
+public class ProtectedTransportIntentCompiler
+        extends ConnectivityIntentCompiler<ProtectedTransportIntent> {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ResourceService resourceService;
+
+    @Activate
+    public void activate() {
+        intentManager.registerCompiler(ProtectedTransportIntent.class, this);
+        log.info("started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        intentManager.unregisterCompiler(ProtectedTransportIntent.class);
+        log.info("stopped");
+    }
+
+    @Override
+    public List<Intent> compile(ProtectedTransportIntent intent,
+                                List<Intent> installable) {
+        log.trace("compiling {} {}", intent, installable);
+
+        // case 0 hop, same device
+        final DeviceId did1 = intent.one();
+        final DeviceId did2 = intent.two();
+        if (Objects.equals(did1, did2)) {
+            // Doesn't really make sense to create 0 hop protected path, but
+            // can generate Flow for the device, just to provide connectivity.
+            // future work.
+            log.error("0 hop not supported yet.");
+            throw new IntentCompilationException("0 hop not supported yet.");
+        }
+
+        List<Intent> reusable = Optional.ofNullable(installable).orElse(ImmutableList.of())
+            .stream()
+            .filter(this::isIntact)
+            .collect(Collectors.toList());
+        if (reusable.isEmpty() ||
+            reusable.stream().allMatch(ProtectionEndpointIntent.class::isInstance)) {
+            // case provisioning new protected path
+            //   or
+            // case re-compilation (total failure -> restoration)
+            return createFreshProtectedPaths(intent, did1, did2);
+        } else {
+            // case re-compilation (partial failure)
+            log.warn("Re-computing adding new backup path not supported yet. No-Op.");
+            // TODO This part needs to be flexible to support various use case
+            // - non-revertive behavior (Similar to PartialFailureConstraint)
+            // - revertive behavior
+            // - compute third path
+            // ...
+            //  Require further input what they actually need.
+
+            // TODO handle PartialFailureConstraint
+
+            /// case only need to update transit portion
+            /// case head and/or tail needs to be updated
+
+            // TODO do we need to prune broken
+            return installable;
+        }
+    }
+
+    /**
+     * Test if resources used by specified Intent is intact.
+     *
+     * @param installed Intent to test
+     * @return true if Intent is intact
+     */
+    private boolean isIntact(Intent installed) {
+        return installed.resources().stream()
+            .filter(Link.class::isInstance)
+            .map(Link.class::cast)
+            .allMatch(this::isLive);
+    }
+
+    /**
+     * Test if specified Link is intact.
+     *
+     * @param link to test
+     * @return true if link is intact
+     */
+    private boolean isLive(Link link) {
+        // Only testing link state for now
+        // in the long run, consider verifying OAM state on ports
+        return link.state() != State.INACTIVE;
+    }
+
+    /**
+     * Creates new protected paths.
+     *
+     * @param intent    original intention
+     * @param did1      identifier of first device
+     * @param did2      identifier of second device
+     * @return compilation result
+     * @throws IntentCompilationException when there's no satisfying path.
+     */
+    private List<Intent> createFreshProtectedPaths(ProtectedTransportIntent intent,
+                                                   DeviceId did1,
+                                                   DeviceId did2) {
+        DisjointPath disjointPath = getDisjointPath(intent, did1, did2);
+        if (disjointPath == null || disjointPath.backup() == null) {
+            log.error("Unable to find disjoint path between {}, {}", did1, did2);
+            throw new IntentCompilationException("Unable to find disjoint paths.");
+        }
+        Path primary = disjointPath.primary();
+        Path secondary = disjointPath.backup();
+
+        String fingerprint = intent.key().toString();
+
+        // pick and allocate Vlan to use as S-tag
+        Pair<VlanId, VlanId> vlans = allocateEach(intent, primary, secondary, VlanId.class);
+
+        VlanId primaryVlan = vlans.getLeft();
+        VlanId secondaryVlan = vlans.getRight();
+
+        // Build edge Intents for head/tail
+
+        // resource for head/tail
+        Collection<NetworkResource> oneResources = new ArrayList<>();
+        Collection<NetworkResource> twoResources = new ArrayList<>();
+
+        List<TransportEndpointDescription> onePaths = new ArrayList<>();
+        onePaths.add(TransportEndpointDescription.builder()
+                         .withOutput(vlanPort(primary.src(), primaryVlan))
+                         .build());
+        onePaths.add(TransportEndpointDescription.builder()
+                         .withOutput(vlanPort(secondary.src(), secondaryVlan))
+                         .build());
+
+        List<TransportEndpointDescription> twoPaths = new ArrayList<>();
+        twoPaths.add(TransportEndpointDescription.builder()
+                     .withOutput(vlanPort(primary.dst(), primaryVlan))
+                     .build());
+        twoPaths.add(TransportEndpointDescription.builder()
+                     .withOutput(vlanPort(secondary.dst(), secondaryVlan))
+                     .build());
+
+        ProtectionEndpointIntent oneIntent = ProtectionEndpointIntent.builder()
+                .key(intent.key())
+                .appId(intent.appId())
+                .priority(intent.priority())
+                .resources(oneResources)
+                .deviceId(did1)
+                .description(buildDescription(onePaths, did2, fingerprint))
+                .build();
+        ProtectionEndpointIntent twoIntent = ProtectionEndpointIntent.builder()
+                .key(intent.key())
+                .appId(intent.appId())
+                .resources(twoResources)
+                .deviceId(did2)
+                .description(buildDescription(twoPaths, did1, fingerprint))
+                .build();
+
+        // Build transit intent for primary/secondary path
+
+        ImmutableList<Intent> result = ImmutableList.<Intent>builder()
+                // LinkCollection for primary and backup paths
+                .addAll(createTransitIntent(intent, primary, primaryVlan))
+                .addAll(createTransitIntent(intent, secondary, secondaryVlan))
+                .add(oneIntent)
+                .add(twoIntent)
+                .build();
+        log.trace("createFreshProtectedPaths result: {}", result);
+        return result;
+    }
+
+    /**
+     * Creates required Intents required to transit bi-directionally the network.
+     *
+     * @param intent parent IntentId
+     * @param path whole path
+     * @param vid VlanId to use as tunnel labels
+     * @return List on transit Intents, if any is required.
+     */
+    List<LinkCollectionIntent> createTransitIntent(Intent intent, Path path, VlanId vid) {
+        if (path.links().size() <= 1) {
+            // There's no need for transit Intents
+            return ImmutableList.of();
+        }
+
+        return ImmutableList.of(createSubTransitIntent(intent, path, vid),
+                                createSubTransitIntent(intent, reverse(path), vid));
+    }
+
+    /**
+     * Returns a path in reverse direction.
+     *
+     * @param path to reverse
+     * @return reversed path
+     */
+    Path reverse(Path path) {
+        List<Link> revLinks = Lists.reverse(transform(path.links(), this::reverse));
+        return new DefaultPath(path.providerId(),
+                               revLinks,
+                               path.cost(),
+                               path.annotations());
+    }
+
+    // TODO consider adding equivalent to Link/DefaultLink.
+    /**
+     * Returns a link in reverse direction.
+     *
+     * @param link to revese
+     * @return reversed link
+     */
+    Link reverse(Link link) {
+        return DefaultLink.builder()
+                .providerId(link.providerId())
+                .src(link.dst())
+                .dst(link.src())
+                .type(link.type())
+                .state(link.state())
+                .isExpected(link.isExpected())
+                .annotations(link.annotations())
+                .build();
+    }
+
+    /**
+     * Creates required Intents required to transit uni-directionally along the Path.
+     *
+     * @param intent parent IntentId
+     * @param path whole path
+     * @param vid VlanId to use as tunnel labels
+     * @return List on transit Intents, if any is required.
+     */
+    LinkCollectionIntent createSubTransitIntent(Intent intent, Path path, VlanId vid) {
+        checkArgument(path.links().size() > 1);
+
+        // transit ingress/egress
+        ConnectPoint one = path.links().get(0).dst();
+        ConnectPoint two = path.links().get(path.links().size() - 1).src();
+
+        return LinkCollectionIntent.builder()
+                    // TODO there should probably be .parent(intent)
+                    // which copies key, appId, priority, ...
+                    .key(intent.key())
+                    .appId(intent.appId())
+                    .priority(intent.priority())
+                    //.constraints(intent.constraints())
+                    // VLAN tunnel
+                    //.selector(DefaultTrafficSelector.builder().matchVlanId(vid).build())
+                    //.treatment(intent.treatment())
+                    .links(ImmutableSet.copyOf(path.links()))
+                    .filteredIngressPoints(ImmutableSet.of(vlanPort(one, vid)))
+                    .filteredEgressPoints(ImmutableSet.of(vlanPort(two, vid)))
+                    // magic flag required for p2p type
+                    .applyTreatmentOnEgress(true)
+                    .cost(path.cost())
+                    .build();
+    }
+
+    /**
+     * Creates VLAN filtered-ConnectPoint.
+     *
+     * @param cp  ConnectPoint
+     * @param vid VLAN ID
+     * @return filtered-ConnectPoint
+     */
+    static FilteredConnectPoint vlanPort(ConnectPoint cp, VlanId vid) {
+        return new FilteredConnectPoint(cp, DefaultTrafficSelector.builder()
+                                        .matchVlanId(vid)
+                                        .build());
+    }
+
+    /**
+     * Creates ResourceId for a port.
+     *
+     * @param cp ConnectPoint
+     * @return ResourceId
+     */
+    static DiscreteResourceId resourceId(ConnectPoint cp) {
+        return Resources.discrete(cp.deviceId(), cp.port()).id();
+    }
+
+    /**
+     * Allocate resource for each {@link Path}s.
+     *
+     * @param intent to allocate resource to
+     * @param primary path
+     * @param secondary path
+     * @param klass label resource class
+     * @return Pair of chosen resource (primary, secondary)
+     * @param <T> label resource type
+     * @throws IntentCompilationException when there is no resource available
+     */
+    <T> Pair<T, T> allocateEach(Intent intent, Path primary, Path secondary, Class<T> klass) {
+        log.trace("allocateEach({}, {}, {}, {})", intent, primary, secondary, klass);
+        Pair<T, T> vlans = null;
+        do {
+            Set<T> primaryVlans = commonLabelResource(primary, klass);
+            Set<T> secondaryVlans = commonLabelResource(secondary, klass);
+            Pair<T, T> candidates = pickEach(primaryVlans, secondaryVlans);
+            T primaryT = candidates.getLeft();
+            T secondaryT = candidates.getRight();
+
+            // try to allocate candidates along each path
+            Stream<Resource> primaryResources = primary.links().stream()
+                    .flatMap(link -> Stream.of(link.src(), link.dst()))
+                    .distinct()
+                    .map(cp -> Resources.discrete(resourceId(cp), primaryT).resource());
+            Stream<Resource> secondaryResources = secondary.links().stream()
+                    .flatMap(link -> Stream.of(link.src(), link.dst()))
+                    .distinct()
+                    .map(cp -> Resources.discrete(resourceId(cp), secondaryT).resource());
+
+            List<Resource> resources = concat(primaryResources, secondaryResources)
+                                        .collect(Collectors.toList());
+            log.trace("Calling allocate({},{})", intent.id(), resources);
+            if (resourceService.allocate(intent.id(), resources).isEmpty()) {
+                log.warn("Allocation failed, retrying");
+                continue;
+            }
+            vlans = candidates;
+        } while (false);
+        log.trace("allocation done.");
+        return vlans;
+    }
+
+    /**
+     * Randomly pick one resource from candidates.
+     *
+     * @param set of candidates
+     * @return chosen one
+     * @param <T> label resource type
+     */
+    <T> T pickOne(Set<T> set) {
+        // Note: Set returned by commonLabelResource(..) assures,
+        // there is at least one element.
+
+        // FIXME more reasonable selection logic
+        return Iterables.get(set, RandomUtils.nextInt(0, set.size()));
+    }
+
+    /**
+     * Select resource from available Resources.
+     *
+     * @param primary   Set of resource to pick from
+     * @param secondary Set of resource to pick from
+     * @return Pair of chosen resource (primary, secondary)
+     * @param <T> label resource type
+     */
+    <T> Pair<T, T> pickEach(Set<T> primary, Set<T> secondary) {
+        Set<T> intersection = Sets.intersection(primary, secondary);
+
+        if (!intersection.isEmpty()) {
+            // favor common
+            T picked = pickOne(intersection);
+            return Pair.of(picked, picked);
+        }
+
+        T pickedP = pickOne(primary);
+        T pickedS = pickOne(secondary);
+        return Pair.of(pickedP, pickedS);
+    }
+
+    /**
+     * Finds label resource, which can be used in common along the path.
+     *
+     * @param path path
+     * @param klass Label class
+     * @return Set of common resources
+     * @throws IntentCompilationException when there is no resource available
+     * @param <T> label resource type
+     */
+    <T> Set<T> commonLabelResource(Path path, Class<T> klass) {
+         Optional<Set<T>> common = path.links().stream()
+            .flatMap(link -> Stream.of(link.src(), link.dst()))
+            .distinct()
+            .map(cp -> getAvailableResourceValues(cp, klass))
+            .reduce(Sets::intersection);
+
+         if (!common.isPresent() || common.get().isEmpty()) {
+             throw new IntentCompilationException("No common label available for: " + path);
+         }
+         return common.get();
+    }
+
+    <T> Set<T> getAvailableResourceValues(ConnectPoint cp, Class<T> klass) {
+        return resourceService.getAvailableResourceValues(
+                                 resourceId(cp),
+                                 klass);
+    }
+
+}
