diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/protection/ProtectedTransportEndpointDescription.java b/core/api/src/main/java/org/onosproject/net/behaviour/protection/ProtectedTransportEndpointDescription.java
index 2e563de..dcdd895 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/protection/ProtectedTransportEndpointDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/protection/ProtectedTransportEndpointDescription.java
@@ -113,14 +113,29 @@
      * Creates a {@link ProtectedTransportEndpointDescription}.
      *
      * @param paths {@link TransportEndpointDescription}s forming protection
-     * @param did DeviceId of remote peer of this endpoint.
+     * @param peer DeviceId of remote peer of this endpoint.
+     * @param fingerprint opaque fingerprint object. must be serializable.
+     * @return {@link TransportEndpointDescription}
+     */
+    public static final ProtectedTransportEndpointDescription
+            buildDescription(List<TransportEndpointDescription> paths,
+                             DeviceId peer,
+                             String fingerprint) {
+        return new ProtectedTransportEndpointDescription(paths, peer, fingerprint);
+    }
+
+    /**
+     * Creates a {@link ProtectedTransportEndpointDescription}.
+     *
+     * @param paths {@link TransportEndpointDescription}s forming protection
+     * @param peer DeviceId of remote peer of this endpoint.
      * @param fingerprint opaque fingerprint object. must be serializable.
      * @return {@link TransportEndpointDescription}
      */
     public static final ProtectedTransportEndpointDescription
                             of(List<TransportEndpointDescription> paths,
-                               DeviceId did,
+                               DeviceId peer,
                                String fingerprint) {
-        return new ProtectedTransportEndpointDescription(paths, did, fingerprint);
+        return new ProtectedTransportEndpointDescription(paths, peer, fingerprint);
     }
 }
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/protection/ProtectionConfig.java b/core/api/src/main/java/org/onosproject/net/behaviour/protection/ProtectionConfig.java
index 1bcafba..085bc1f 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/protection/ProtectionConfig.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/protection/ProtectionConfig.java
@@ -16,6 +16,7 @@
 package org.onosproject.net.behaviour.protection;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.behaviour.protection.ProtectedTransportEndpointDescription.buildDescription;
 
 import java.util.List;
 
@@ -127,7 +128,7 @@
      * @return {@link ProtectedTransportEndpointDescription}
      */
     public ProtectedTransportEndpointDescription asDescription() {
-        return ProtectedTransportEndpointDescription.of(paths(), peer(), fingerprint());
+        return buildDescription(paths(), peer(), fingerprint());
     }
 
     @Override
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);
+    }
+
+}
