diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompiler.java
index c3f46ef..427d56d 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompiler.java
@@ -16,6 +16,7 @@
 package org.onosproject.net.intent.impl.compiler;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -23,6 +24,8 @@
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.onosproject.net.DefaultLink;
 import org.onosproject.net.DefaultPath;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.Host;
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
@@ -30,15 +33,22 @@
 import org.onosproject.net.host.HostService;
 import org.onosproject.net.intent.HostToHostIntent;
 import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentCompilationException;
+import org.onosproject.net.intent.LinkCollectionIntent;
 import org.onosproject.net.intent.PathIntent;
 import org.onosproject.net.intent.constraint.AsymmetricPathConstraint;
+import org.slf4j.Logger;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
 
+import static org.onosproject.net.Link.Type.EDGE;
 import static org.onosproject.net.flow.DefaultTrafficSelector.builder;
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * A intent compiler for {@link HostToHostIntent}.
@@ -47,6 +57,10 @@
 public class HostToHostIntentCompiler
         extends ConnectivityIntentCompiler<HostToHostIntent> {
 
+    private final Logger log = getLogger(getClass());
+
+    private static final String DEVICE_ID_NOT_FOUND = "Didn't find device id in the link";
+
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected HostService hostService;
 
@@ -75,8 +89,8 @@
         Host one = hostService.getHost(intent.one());
         Host two = hostService.getHost(intent.two());
 
-        return Arrays.asList(createPathIntent(pathOne, one, two, intent),
-                             createPathIntent(pathTwo, two, one, intent));
+        return Arrays.asList(createLinkCollectionIntent(pathOne, one, two, intent),
+                             createLinkCollectionIntent(pathTwo, two, one, intent));
     }
 
     // Inverts the specified path. This makes an assumption that each link in
@@ -116,4 +130,58 @@
                 .build();
     }
 
+    private FilteredConnectPoint getFilteredPointFromLink(Link link) {
+        FilteredConnectPoint filteredConnectPoint;
+        if (link.src().elementId() instanceof DeviceId) {
+            filteredConnectPoint = new FilteredConnectPoint(link.src());
+        } else if (link.dst().elementId() instanceof DeviceId) {
+            filteredConnectPoint = new FilteredConnectPoint(link.dst());
+        } else {
+            throw new IntentCompilationException(DEVICE_ID_NOT_FOUND);
+        }
+        return filteredConnectPoint;
+    }
+
+    private Intent createLinkCollectionIntent(Path path,
+                                             Host src,
+                                             Host dst,
+                                             HostToHostIntent intent) {
+        /*
+         * The path contains also the edge links, these are not necessary
+         * for the LinkCollectionIntent.
+         */
+        Set<Link> coreLinks = path.links()
+                .stream()
+                .filter(link -> !link.type().equals(EDGE))
+                .collect(Collectors.toSet());
+
+        Link ingressLink = path.links().get(0);
+        Link egressLink = path.links().get(path.links().size() - 1);
+
+        FilteredConnectPoint ingressPoint = getFilteredPointFromLink(ingressLink);
+        FilteredConnectPoint egressPoint = getFilteredPointFromLink(egressLink);
+
+        TrafficSelector selector = builder(intent.selector())
+                .matchEthSrc(src.mac())
+                .matchEthDst(dst.mac())
+                .build();
+
+        return LinkCollectionIntent.builder()
+                .key(intent.key())
+                .appId(intent.appId())
+                .selector(selector)
+                .treatment(intent.treatment())
+                .links(coreLinks)
+                .filteredIngressPoints(ImmutableSet.of(
+                        ingressPoint
+                ))
+                .filteredEgressPoints(ImmutableSet.of(
+                        egressPoint
+                ))
+                .applyTreatmentOnEgress(true)
+                .constraints(intent.constraints())
+                .priority(intent.priority())
+                .build();
+    }
+
 }
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompilerTest.java
index 939cab0..4dc5045 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompilerTest.java
@@ -15,13 +15,18 @@
  */
 package org.onosproject.net.intent.impl.compiler;
 
+import com.google.common.collect.ImmutableSet;
 import org.hamcrest.Matchers;
 import org.junit.Before;
 import org.junit.Test;
-import org.onosproject.core.ApplicationId;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
 import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.Host;
 import org.onosproject.net.HostId;
+import org.onosproject.net.Link;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.host.HostService;
@@ -29,18 +34,18 @@
 import org.onosproject.net.intent.HostToHostIntent;
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentTestsMocks;
-import org.onosproject.net.intent.PathIntent;
+import org.onosproject.net.intent.LinkCollectionIntent;
 import org.onosproject.net.resource.MockResourceService;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
 
 import java.util.List;
+import java.util.Set;
 
 import static org.easymock.EasyMock.*;
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
+import static org.onosproject.net.NetTestTools.connectPoint;
 import static org.onosproject.net.NetTestTools.hid;
 import static org.onosproject.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;
 
@@ -55,6 +60,17 @@
     private static final String HOST_ONE = HOST_ONE_MAC + "/" + HOST_ONE_VLAN;
     private static final String HOST_TWO = HOST_TWO_MAC + "/" + HOST_TWO_VLAN;
 
+    private static final int PORT_1 = 1;
+
+    private static final String HOP_1 = "h1";
+    private static final String HOP_2 = "h2";
+    private static final String HOP_3 = "h3";
+    private static final String HOP_4 = "h4";
+    private static final String HOP_5 = "h5";
+    private static final String HOP_6 = "h6";
+    private static final String HOP_7 = "h7";
+    private static final String HOP_8 = "h8";
+
     private static final ApplicationId APPID = new TestApplicationId("foo");
 
     private TrafficSelector selector = new IntentTestsMocks.MockSelector();
@@ -126,44 +142,51 @@
                                              HOST_TWO);
         assertThat(intent, is(notNullValue()));
 
-        String[] hops = {HOST_ONE, "h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8", HOST_TWO};
+        String[] hops = {HOST_ONE, HOP_1, HOP_2, HOP_3, HOP_4, HOP_5, HOP_6, HOP_7, HOP_8, HOST_TWO};
         HostToHostIntentCompiler compiler = makeCompiler(hops);
         assertThat(compiler, is(notNullValue()));
 
         List<Intent> result = compiler.compile(intent, null);
         assertThat(result, is(Matchers.notNullValue()));
         assertThat(result, hasSize(2));
-        Intent forwardResultIntent = result.get(0);
-        assertThat(forwardResultIntent instanceof PathIntent, is(true));
-        Intent reverseResultIntent = result.get(1);
-        assertThat(reverseResultIntent instanceof PathIntent, is(true));
+        Intent forwardIntent = result.get(0);
+        assertThat(forwardIntent instanceof LinkCollectionIntent, is(true));
+        Intent reverseIntent = result.get(1);
+        assertThat(reverseIntent instanceof LinkCollectionIntent, is(true));
 
-        if (forwardResultIntent instanceof PathIntent) {
-            PathIntent forwardPathIntent = (PathIntent) forwardResultIntent;
-            assertThat(forwardPathIntent.path().links(), hasSize(9));
-            assertThat(forwardPathIntent.path().links(), linksHasPath(HOST_ONE, "h1"));
-            assertThat(forwardPathIntent.path().links(), linksHasPath("h1", "h2"));
-            assertThat(forwardPathIntent.path().links(), linksHasPath("h2", "h3"));
-            assertThat(forwardPathIntent.path().links(), linksHasPath("h3", "h4"));
-            assertThat(forwardPathIntent.path().links(), linksHasPath("h4", "h5"));
-            assertThat(forwardPathIntent.path().links(), linksHasPath("h5", "h6"));
-            assertThat(forwardPathIntent.path().links(), linksHasPath("h6", "h7"));
-            assertThat(forwardPathIntent.path().links(), linksHasPath("h7", "h8"));
-            assertThat(forwardPathIntent.path().links(), linksHasPath("h8", HOST_TWO));
-        }
+        LinkCollectionIntent forwardLCIntent = (LinkCollectionIntent) forwardIntent;
+        Set<Link> links = forwardLCIntent.links();
+        assertThat(links, hasSize(7));
+        Set<FilteredConnectPoint> ingressPoints = ImmutableSet.of(
+                new FilteredConnectPoint(connectPoint(HOP_1, PORT_1))
+        );
+        assertThat(forwardLCIntent.filteredIngressPoints(), is(ingressPoints));
+        assertThat(links, linksHasPath(HOP_1, HOP_2));
+        assertThat(links, linksHasPath(HOP_2, HOP_3));
+        assertThat(links, linksHasPath(HOP_3, HOP_4));
+        assertThat(links, linksHasPath(HOP_4, HOP_5));
+        assertThat(links, linksHasPath(HOP_5, HOP_6));
+        assertThat(links, linksHasPath(HOP_6, HOP_7));
+        assertThat(links, linksHasPath(HOP_7, HOP_8));
+        Set<FilteredConnectPoint> egressPoints = ImmutableSet.of(
+                new FilteredConnectPoint(connectPoint(HOP_8, PORT_1))
+        );
+        assertThat(forwardLCIntent.filteredEgressPoints(), is(egressPoints));
 
-        if (reverseResultIntent instanceof PathIntent) {
-            PathIntent reversePathIntent = (PathIntent) reverseResultIntent;
-            assertThat(reversePathIntent.path().links(), hasSize(9));
-            assertThat(reversePathIntent.path().links(), linksHasPath("h1", HOST_ONE));
-            assertThat(reversePathIntent.path().links(), linksHasPath("h2", "h1"));
-            assertThat(reversePathIntent.path().links(), linksHasPath("h3", "h2"));
-            assertThat(reversePathIntent.path().links(), linksHasPath("h4", "h3"));
-            assertThat(reversePathIntent.path().links(), linksHasPath("h5", "h4"));
-            assertThat(reversePathIntent.path().links(), linksHasPath("h6", "h5"));
-            assertThat(reversePathIntent.path().links(), linksHasPath("h7", "h6"));
-            assertThat(reversePathIntent.path().links(), linksHasPath("h8", "h7"));
-            assertThat(reversePathIntent.path().links(), linksHasPath(HOST_TWO, "h8"));
-        }
+        LinkCollectionIntent reverseLCIntent = (LinkCollectionIntent) reverseIntent;
+        links = reverseLCIntent.links();
+        assertThat(reverseLCIntent.links(), hasSize(7));
+        ingressPoints = ImmutableSet.of(new FilteredConnectPoint(connectPoint(HOP_8, PORT_1)));
+        assertThat(reverseLCIntent.filteredIngressPoints(), is(ingressPoints));
+        assertThat(links, linksHasPath(HOP_2, HOP_1));
+        assertThat(links, linksHasPath(HOP_3, HOP_2));
+        assertThat(links, linksHasPath(HOP_4, HOP_3));
+        assertThat(links, linksHasPath(HOP_5, HOP_4));
+        assertThat(links, linksHasPath(HOP_6, HOP_5));
+        assertThat(links, linksHasPath(HOP_7, HOP_6));
+        assertThat(links, linksHasPath(HOP_8, HOP_7));
+        egressPoints = ImmutableSet.of(new FilteredConnectPoint(connectPoint(HOP_1, PORT_1)));
+        assertThat(reverseLCIntent.filteredEgressPoints(), is(egressPoints));
+
     }
 }
