diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/AbstractFabricHandlerBehavior.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/AbstractFabricHandlerBehavior.java
new file mode 100644
index 0000000..fe07576
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/AbstractFabricHandlerBehavior.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.pi.model.PiPipeconfId;
+import org.onosproject.net.pi.service.PiPipeconfService;
+import org.slf4j.Logger;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Abstract implementation of HandlerBehaviour for the fabric pipeconf
+ * behaviors.
+ * <p>
+ * All sub-classes must implement a default constructor, used by the abstract
+ * projectable model (i.e., {@link org.onosproject.net.Device#as(Class)}.
+ */
+public abstract class AbstractFabricHandlerBehavior extends AbstractHandlerBehaviour {
+
+    protected final Logger log = getLogger(getClass());
+
+    protected FabricCapabilities capabilities;
+
+    /**
+     * Creates a new instance of this behavior with the given capabilities.
+     * Note: this constructor should be invoked only by other classes of this
+     * package that can retrieve capabilities on their own.
+     * <p>
+     * When using the abstract projectable model (i.e., {@link
+     * org.onosproject.net.Device#as(Class)}, capabilities will be set by the
+     * driver manager when calling {@link #setHandler(DriverHandler)})
+     *
+     * @param capabilities capabilities
+     */
+    protected AbstractFabricHandlerBehavior(FabricCapabilities capabilities) {
+        this.capabilities = capabilities;
+    }
+
+    /**
+     * Create a new instance of this behaviour. Used by the abstract projectable
+     * model (i.e., {@link org.onosproject.net.Device#as(Class)}.
+     */
+    public AbstractFabricHandlerBehavior() {
+        // Do nothing
+    }
+
+    @Override
+    public void setHandler(DriverHandler handler) {
+        super.setHandler(handler);
+        final PiPipeconfService pipeconfService = handler().get(PiPipeconfService.class);
+        setCapabilitiesFromHandler(handler().data().deviceId(), pipeconfService);
+    }
+
+    private void setCapabilitiesFromHandler(
+            DeviceId deviceId, PiPipeconfService pipeconfService) {
+        checkNotNull(deviceId);
+        checkNotNull(pipeconfService);
+        // Get pipeconf capabilities.
+        final PiPipeconfId pipeconfId = pipeconfService.ofDevice(deviceId)
+                .orElse(null);
+        if (pipeconfId == null) {
+            throw new IllegalStateException(format(
+                    "Unable to get pipeconf ID of device %s", deviceId.toString()));
+        }
+        if (!pipeconfService.getPipeconf(pipeconfId).isPresent()) {
+            throw new IllegalStateException(format(
+                    "Pipeconf '%s' is not registered ", pipeconfId));
+        }
+        this.capabilities = new FabricCapabilities(
+                pipeconfService.getPipeconf(pipeconfId).get());
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricCapabilities.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricCapabilities.java
new file mode 100644
index 0000000..6def74f
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricCapabilities.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour;
+
+import org.onosproject.net.pi.model.PiPipeconf;
+import org.slf4j.Logger;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.CPU_PORT_TXT;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Representation of the capabilities of a given fabric pipeconf.
+ */
+public class FabricCapabilities {
+
+    private final Logger log = getLogger(getClass());
+
+    private final PiPipeconf pipeconf;
+
+    public FabricCapabilities(PiPipeconf pipeconf) {
+        this.pipeconf = checkNotNull(pipeconf);
+    }
+
+    public boolean hasHashedTable() {
+        return pipeconf.pipelineModel()
+                .table(FabricConstants.FABRIC_INGRESS_NEXT_HASHED).isPresent();
+    }
+
+    public Optional<Integer> cpuPort() {
+        // This is probably brittle, but needed to dynamically get the CPU port
+        // for different platforms.
+        if (!pipeconf.extension(CPU_PORT_TXT).isPresent()) {
+            log.warn("Missing {} extension in pipeconf {}", CPU_PORT_TXT, pipeconf.id());
+            return Optional.empty();
+        }
+        try {
+            final InputStream stream = pipeconf.extension(CPU_PORT_TXT).get();
+            final BufferedReader buff = new BufferedReader(
+                    new InputStreamReader(stream));
+            final String str = buff.readLine();
+            buff.close();
+            if (str == null) {
+                log.error("Empty CPU port file for {}", pipeconf.id());
+                return Optional.empty();
+            }
+            try {
+                return Optional.of(Integer.parseInt(str));
+            } catch (NumberFormatException e) {
+                log.error("Invalid CPU port for {}: {}", pipeconf.id(), str);
+                return Optional.empty();
+            }
+        } catch (IOException e) {
+            log.error("Unable to read CPU port file of {}: {}",
+                      pipeconf.id(), e.getMessage());
+            return Optional.empty();
+        }
+    }
+
+    public boolean supportDoubleVlanTerm() {
+        if (pipeconf.pipelineModel()
+                .table(FabricConstants.FABRIC_INGRESS_NEXT_NEXT_VLAN).isPresent()) {
+            return pipeconf.pipelineModel().table(FabricConstants.FABRIC_INGRESS_NEXT_NEXT_VLAN)
+                    .get().action(FabricConstants.FABRIC_INGRESS_NEXT_SET_DOUBLE_VLAN)
+                    .isPresent();
+        }
+        return false;
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricConstants.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricConstants.java
new file mode 100644
index 0000000..c10f3f5
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricConstants.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour;
+
+import org.onosproject.net.pi.model.PiActionId;
+import org.onosproject.net.pi.model.PiActionParamId;
+import org.onosproject.net.pi.model.PiActionProfileId;
+import org.onosproject.net.pi.model.PiCounterId;
+import org.onosproject.net.pi.model.PiMatchFieldId;
+import org.onosproject.net.pi.model.PiMeterId;
+import org.onosproject.net.pi.model.PiPacketMetadataId;
+import org.onosproject.net.pi.model.PiTableId;
+/**
+ * Constants for fabric pipeline.
+ */
+public final class FabricConstants {
+
+    // hide default constructor
+    private FabricConstants() {
+    }
+
+    // Header field IDs
+    public static final PiMatchFieldId HDR_IG_PORT =
+            PiMatchFieldId.of("ig_port");
+    public static final PiMatchFieldId HDR_VLAN_IS_VALID =
+            PiMatchFieldId.of("vlan_is_valid");
+    public static final PiMatchFieldId HDR_EG_PORT =
+            PiMatchFieldId.of("eg_port");
+    public static final PiMatchFieldId HDR_IPV6_SRC_NET_ID =
+            PiMatchFieldId.of("ipv6_src_net_id");
+    public static final PiMatchFieldId HDR_C_TAG = PiMatchFieldId.of("c_tag");
+    public static final PiMatchFieldId HDR_IPV4_SRC =
+            PiMatchFieldId.of("ipv4_src");
+    public static final PiMatchFieldId HDR_IPV6_DST =
+            PiMatchFieldId.of("ipv6_dst");
+    public static final PiMatchFieldId HDR_IS_MPLS =
+            PiMatchFieldId.of("is_mpls");
+    public static final PiMatchFieldId HDR_L4_DPORT =
+            PiMatchFieldId.of("l4_dport");
+    public static final PiMatchFieldId HDR_PPPOE_CODE =
+            PiMatchFieldId.of("pppoe_code");
+    public static final PiMatchFieldId HDR_IPV6_SRC =
+            PiMatchFieldId.of("ipv6_src");
+    public static final PiMatchFieldId HDR_ETH_SRC =
+            PiMatchFieldId.of("eth_src");
+    public static final PiMatchFieldId HDR_S_TAG = PiMatchFieldId.of("s_tag");
+    public static final PiMatchFieldId HDR_VLAN_ID =
+            PiMatchFieldId.of("vlan_id");
+    public static final PiMatchFieldId HDR_ETH_DST =
+            PiMatchFieldId.of("eth_dst");
+    public static final PiMatchFieldId HDR_ICMP_TYPE =
+            PiMatchFieldId.of("icmp_type");
+    public static final PiMatchFieldId HDR_IPV4_DST =
+            PiMatchFieldId.of("ipv4_dst");
+    public static final PiMatchFieldId HDR_IPV6_TRAFFIC_CLASS =
+            PiMatchFieldId.of("ipv6_traffic_class");
+    public static final PiMatchFieldId HDR_ETH_TYPE =
+            PiMatchFieldId.of("eth_type");
+    public static final PiMatchFieldId HDR_NEXT_ID =
+            PiMatchFieldId.of("next_id");
+    public static final PiMatchFieldId HDR_L4_SPORT =
+            PiMatchFieldId.of("l4_sport");
+    public static final PiMatchFieldId HDR_ICMP_CODE =
+            PiMatchFieldId.of("icmp_code");
+    public static final PiMatchFieldId HDR_INNER_VLAN_ID =
+            PiMatchFieldId.of("inner_vlan_id");
+    public static final PiMatchFieldId HDR_IPV4_ECN =
+            PiMatchFieldId.of("ipv4_ecn");
+    public static final PiMatchFieldId HDR_PPPOE_SESSION_ID =
+            PiMatchFieldId.of("pppoe_session_id");
+    public static final PiMatchFieldId HDR_EG_SPEC =
+            PiMatchFieldId.of("eg_spec");
+    public static final PiMatchFieldId HDR_LINE_ID =
+            PiMatchFieldId.of("line_id");
+    public static final PiMatchFieldId HDR_IPV4_DSCP =
+            PiMatchFieldId.of("ipv4_dscp");
+    public static final PiMatchFieldId HDR_IS_IPV4 =
+            PiMatchFieldId.of("is_ipv4");
+    public static final PiMatchFieldId HDR_IS_IPV6 =
+            PiMatchFieldId.of("is_ipv6");
+    public static final PiMatchFieldId HDR_GTP_IPV4_DST =
+            PiMatchFieldId.of("gtp_ipv4_dst");
+    public static final PiMatchFieldId HDR_INT_IS_VALID =
+            PiMatchFieldId.of("int_is_valid");
+    public static final PiMatchFieldId HDR_MPLS_LABEL =
+            PiMatchFieldId.of("mpls_label");
+    public static final PiMatchFieldId HDR_IP_PROTO =
+            PiMatchFieldId.of("ip_proto");
+    public static final PiMatchFieldId HDR_PPPOE_PROTOCOL =
+            PiMatchFieldId.of("pppoe_protocol");
+    // Table IDs
+    public static final PiTableId FABRIC_INGRESS_NEXT_HASHED =
+            PiTableId.of("FabricIngress.next.hashed");
+    public static final PiTableId FABRIC_INGRESS_BNG_INGRESS_T_LINE_MAP =
+            PiTableId.of("FabricIngress.bng_ingress.t_line_map");
+    public static final PiTableId FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_TRANSIT_TB_INT_INSERT =
+            PiTableId.of("FabricEgress.process_int_main.process_int_transit.tb_int_insert");
+    public static final PiTableId FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER =
+            PiTableId.of("FabricIngress.filtering.fwd_classifier");
+    public static final PiTableId FABRIC_INGRESS_NEXT_XCONNECT =
+            PiTableId.of("FabricIngress.next.xconnect");
+    public static final PiTableId FABRIC_INGRESS_NEXT_NEXT_VLAN =
+            PiTableId.of("FabricIngress.next.next_vlan");
+    public static final PiTableId FABRIC_INGRESS_NEXT_SIMPLE =
+            PiTableId.of("FabricIngress.next.simple");
+    public static final PiTableId FABRIC_INGRESS_NEXT_MULTICAST =
+            PiTableId.of("FabricIngress.next.multicast");
+    public static final PiTableId FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_TB_INT_SOURCE =
+            PiTableId.of("FabricEgress.process_int_main.process_int_source.tb_int_source");
+    public static final PiTableId FABRIC_INGRESS_FORWARDING_ROUTING_V6 =
+            PiTableId.of("FabricIngress.forwarding.routing_v6");
+    public static final PiTableId FABRIC_INGRESS_FORWARDING_MPLS =
+            PiTableId.of("FabricIngress.forwarding.mpls");
+    public static final PiTableId FABRIC_INGRESS_FORWARDING_ROUTING_V4 =
+            PiTableId.of("FabricIngress.forwarding.routing_v4");
+    public static final PiTableId FABRIC_INGRESS_ACL_ACL =
+            PiTableId.of("FabricIngress.acl.acl");
+    public static final PiTableId FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN =
+            PiTableId.of("FabricIngress.filtering.ingress_port_vlan");
+    public static final PiTableId FABRIC_INGRESS_BNG_INGRESS_UPSTREAM_T_PPPOE_CP =
+            PiTableId.of("FabricIngress.bng_ingress.upstream.t_pppoe_cp");
+    public static final PiTableId FABRIC_INGRESS_BNG_INGRESS_UPSTREAM_T_PPPOE_TERM_V4 =
+            PiTableId.of("FabricIngress.bng_ingress.upstream.t_pppoe_term_v4");
+    public static final PiTableId FABRIC_INGRESS_SPGW_INGRESS_S1U_FILTER_TABLE =
+            PiTableId.of("FabricIngress.spgw_ingress.s1u_filter_table");
+    public static final PiTableId FABRIC_INGRESS_FORWARDING_BRIDGING =
+            PiTableId.of("FabricIngress.forwarding.bridging");
+    public static final PiTableId FABRIC_INGRESS_SPGW_INGRESS_DL_SESS_LOOKUP =
+            PiTableId.of("FabricIngress.spgw_ingress.dl_sess_lookup");
+    public static final PiTableId FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_T_LINE_SESSION_MAP =
+            PiTableId.of("FabricIngress.bng_ingress.downstream.t_line_session_map");
+    public static final PiTableId FABRIC_EGRESS_EGRESS_NEXT_EGRESS_VLAN =
+            PiTableId.of("FabricEgress.egress_next.egress_vlan");
+    public static final PiTableId FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SINK =
+            PiTableId.of("FabricIngress.process_set_source_sink.tb_set_sink");
+    public static final PiTableId FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_REPORT_TB_GENERATE_REPORT =
+            PiTableId.of("FabricEgress.process_int_main.process_int_report.tb_generate_report");
+    public static final PiTableId FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SOURCE =
+            PiTableId.of("FabricIngress.process_set_source_sink.tb_set_source");
+    public static final PiTableId FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_T_QOS_V6 =
+            PiTableId.of("FabricIngress.bng_ingress.downstream.t_qos_v6");
+    public static final PiTableId FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_T_QOS_V4 =
+            PiTableId.of("FabricIngress.bng_ingress.downstream.t_qos_v4");
+    public static final PiTableId FABRIC_INGRESS_BNG_INGRESS_UPSTREAM_T_PPPOE_TERM_V6 =
+            PiTableId.of("FabricIngress.bng_ingress.upstream.t_pppoe_term_v6");
+    // Indirect Counter IDs
+    public static final PiCounterId FABRIC_EGRESS_BNG_EGRESS_DOWNSTREAM_C_LINE_TX =
+            PiCounterId.of("FabricEgress.bng_egress.downstream.c_line_tx");
+    public static final PiCounterId FABRIC_INGRESS_PORT_COUNTERS_CONTROL_EGRESS_PORT_COUNTER =
+            PiCounterId.of("FabricIngress.port_counters_control.egress_port_counter");
+    public static final PiCounterId FABRIC_INGRESS_BNG_INGRESS_UPSTREAM_C_DROPPED =
+            PiCounterId.of("FabricIngress.bng_ingress.upstream.c_dropped");
+    public static final PiCounterId FABRIC_INGRESS_BNG_INGRESS_UPSTREAM_C_CONTROL =
+            PiCounterId.of("FabricIngress.bng_ingress.upstream.c_control");
+    public static final PiCounterId FABRIC_INGRESS_BNG_INGRESS_UPSTREAM_C_TERMINATED =
+            PiCounterId.of("FabricIngress.bng_ingress.upstream.c_terminated");
+    public static final PiCounterId FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_C_LINE_RX =
+            PiCounterId.of("FabricIngress.bng_ingress.downstream.c_line_rx");
+    public static final PiCounterId FABRIC_INGRESS_PORT_COUNTERS_CONTROL_INGRESS_PORT_COUNTER =
+            PiCounterId.of("FabricIngress.port_counters_control.ingress_port_counter");
+    // Direct Counter IDs
+    public static final PiCounterId FABRIC_INGRESS_NEXT_MULTICAST_COUNTER =
+            PiCounterId.of("FabricIngress.next.multicast_counter");
+    public static final PiCounterId FABRIC_INGRESS_NEXT_SIMPLE_COUNTER =
+            PiCounterId.of("FabricIngress.next.simple_counter");
+    public static final PiCounterId FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER_COUNTER =
+            PiCounterId.of("FabricIngress.filtering.fwd_classifier_counter");
+    public static final PiCounterId FABRIC_INGRESS_FORWARDING_BRIDGING_COUNTER =
+            PiCounterId.of("FabricIngress.forwarding.bridging_counter");
+    public static final PiCounterId FABRIC_INGRESS_FORWARDING_ROUTING_V4_COUNTER =
+            PiCounterId.of("FabricIngress.forwarding.routing_v4_counter");
+    public static final PiCounterId FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_COUNTER_SET_SOURCE =
+            PiCounterId.of("FabricIngress.process_set_source_sink.counter_set_source");
+    public static final PiCounterId FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_COUNTER_INT_SOURCE =
+            PiCounterId.of("FabricEgress.process_int_main.process_int_source.counter_int_source");
+    public static final PiCounterId FABRIC_INGRESS_SPGW_INGRESS_UE_COUNTER =
+            PiCounterId.of("FabricIngress.spgw_ingress.ue_counter");
+    public static final PiCounterId FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_COUNTER_SET_SINK =
+            PiCounterId.of("FabricIngress.process_set_source_sink.counter_set_sink");
+    public static final PiCounterId FABRIC_EGRESS_EGRESS_NEXT_EGRESS_VLAN_COUNTER =
+            PiCounterId.of("FabricEgress.egress_next.egress_vlan_counter");
+    public static final PiCounterId FABRIC_INGRESS_ACL_ACL_COUNTER =
+            PiCounterId.of("FabricIngress.acl.acl_counter");
+    public static final PiCounterId FABRIC_INGRESS_NEXT_XCONNECT_COUNTER =
+            PiCounterId.of("FabricIngress.next.xconnect_counter");
+    public static final PiCounterId FABRIC_INGRESS_NEXT_NEXT_VLAN_COUNTER =
+            PiCounterId.of("FabricIngress.next.next_vlan_counter");
+    public static final PiCounterId FABRIC_INGRESS_FORWARDING_ROUTING_V6_COUNTER =
+            PiCounterId.of("FabricIngress.forwarding.routing_v6_counter");
+    public static final PiCounterId FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN_COUNTER =
+            PiCounterId.of("FabricIngress.filtering.ingress_port_vlan_counter");
+    public static final PiCounterId FABRIC_INGRESS_FORWARDING_MPLS_COUNTER =
+            PiCounterId.of("FabricIngress.forwarding.mpls_counter");
+    public static final PiCounterId FABRIC_INGRESS_NEXT_HASHED_COUNTER =
+            PiCounterId.of("FabricIngress.next.hashed_counter");
+    // Action IDs
+    public static final PiActionId FABRIC_INGRESS_NEXT_SET_NEXT_ID_XCONNECT =
+            PiActionId.of("FabricIngress.next.set_next_id_xconnect");
+    public static final PiActionId FABRIC_INGRESS_FORWARDING_NOP_ROUTING_V4 =
+            PiActionId.of("FabricIngress.forwarding.nop_routing_v4");
+    public static final PiActionId FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_QOS_BESTEFF =
+            PiActionId.of("FabricIngress.bng_ingress.downstream.qos_besteff");
+    public static final PiActionId FABRIC_INGRESS_FILTERING_PERMIT_WITH_INTERNAL_VLAN =
+            PiActionId.of("FabricIngress.filtering.permit_with_internal_vlan");
+    public static final PiActionId FABRIC_INGRESS_NEXT_ROUTING_HASHED =
+            PiActionId.of("FabricIngress.next.routing_hashed");
+    public static final PiActionId FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_BRIDGING =
+            PiActionId.of("FabricIngress.forwarding.set_next_id_bridging");
+    public static final PiActionId FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_INT_SOURCE_DSCP =
+            PiActionId.of("FabricEgress.process_int_main.process_int_source.int_source_dscp");
+    public static final PiActionId FABRIC_INGRESS_NEXT_SET_DOUBLE_VLAN =
+            PiActionId.of("FabricIngress.next.set_double_vlan");
+    public static final PiActionId FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_TRANSIT_INIT_METADATA =
+            PiActionId.of("FabricEgress.process_int_main.process_int_transit.init_metadata");
+    public static final PiActionId FABRIC_INGRESS_ACL_DROP =
+            PiActionId.of("FabricIngress.acl.drop");
+    public static final PiActionId FABRIC_INGRESS_ACL_SET_CLONE_SESSION_ID =
+            PiActionId.of("FabricIngress.acl.set_clone_session_id");
+    public static final PiActionId FABRIC_INGRESS_BNG_INGRESS_UPSTREAM_PUNT_TO_CPU =
+            PiActionId.of("FabricIngress.bng_ingress.upstream.punt_to_cpu");
+    public static final PiActionId FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_DROP =
+            PiActionId.of("FabricIngress.bng_ingress.downstream.drop");
+    public static final PiActionId FABRIC_INGRESS_NEXT_SET_VLAN =
+            PiActionId.of("FabricIngress.next.set_vlan");
+    public static final PiActionId FABRIC_INGRESS_ACL_NOP_ACL =
+            PiActionId.of("FabricIngress.acl.nop_acl");
+    public static final PiActionId FABRIC_INGRESS_BNG_INGRESS_SET_LINE =
+            PiActionId.of("FabricIngress.bng_ingress.set_line");
+    public static final PiActionId FABRIC_INGRESS_BNG_INGRESS_UPSTREAM_TERM_DISABLED =
+            PiActionId.of("FabricIngress.bng_ingress.upstream.term_disabled");
+    public static final PiActionId FABRIC_INGRESS_ACL_SET_NEXT_ID_ACL =
+            PiActionId.of("FabricIngress.acl.set_next_id_acl");
+    public static final PiActionId FABRIC_INGRESS_FILTERING_PERMIT =
+            PiActionId.of("FabricIngress.filtering.permit");
+    public static final PiActionId FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V4 =
+            PiActionId.of("FabricIngress.forwarding.set_next_id_routing_v4");
+    public static final PiActionId FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V6 =
+            PiActionId.of("FabricIngress.forwarding.set_next_id_routing_v6");
+    public static final PiActionId FABRIC_INGRESS_NEXT_ROUTING_SIMPLE =
+            PiActionId.of("FabricIngress.next.routing_simple");
+    public static final PiActionId FABRIC_INGRESS_SPGW_INGRESS_SET_DL_SESS_INFO =
+            PiActionId.of("FabricIngress.spgw_ingress.set_dl_sess_info");
+    public static final PiActionId FABRIC_EGRESS_BNG_EGRESS_DOWNSTREAM_ENCAP_V4 =
+            PiActionId.of("FabricEgress.bng_egress.downstream.encap_v4");
+    public static final PiActionId FABRIC_INGRESS_NEXT_OUTPUT_HASHED =
+            PiActionId.of("FabricIngress.next.output_hashed");
+    public static final PiActionId FABRIC_INGRESS_FORWARDING_POP_MPLS_AND_NEXT =
+            PiActionId.of("FabricIngress.forwarding.pop_mpls_and_next");
+    public static final PiActionId FABRIC_EGRESS_BNG_EGRESS_DOWNSTREAM_ENCAP_V6 =
+            PiActionId.of("FabricEgress.bng_egress.downstream.encap_v6");
+    public static final PiActionId FABRIC_INGRESS_NEXT_MPLS_ROUTING_SIMPLE =
+            PiActionId.of("FabricIngress.next.mpls_routing_simple");
+    public static final PiActionId FABRIC_INGRESS_ACL_PUNT_TO_CPU =
+            PiActionId.of("FabricIngress.acl.punt_to_cpu");
+    public static final PiActionId FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_QOS_PRIO =
+            PiActionId.of("FabricIngress.bng_ingress.downstream.qos_prio");
+    public static final PiActionId FABRIC_EGRESS_EGRESS_NEXT_POP_VLAN =
+            PiActionId.of("FabricEgress.egress_next.pop_vlan");
+    public static final PiActionId FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_INT_SET_SINK =
+            PiActionId.of("FabricIngress.process_set_source_sink.int_set_sink");
+    public static final PiActionId FABRIC_INGRESS_NEXT_MPLS_ROUTING_HASHED =
+            PiActionId.of("FabricIngress.next.mpls_routing_hashed");
+    public static final PiActionId FABRIC_INGRESS_BNG_INGRESS_UPSTREAM_TERM_ENABLED_V6 =
+            PiActionId.of("FabricIngress.bng_ingress.upstream.term_enabled_v6");
+    public static final PiActionId FABRIC_INGRESS_BNG_INGRESS_UPSTREAM_TERM_ENABLED_V4 =
+            PiActionId.of("FabricIngress.bng_ingress.upstream.term_enabled_v4");
+    public static final PiActionId FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_INT_SET_SOURCE =
+            PiActionId.of("FabricIngress.process_set_source_sink.int_set_source");
+    public static final PiActionId NOP = PiActionId.of("nop");
+    public static final PiActionId FABRIC_INGRESS_NEXT_OUTPUT_SIMPLE =
+            PiActionId.of("FabricIngress.next.output_simple");
+    public static final PiActionId FABRIC_INGRESS_FILTERING_DENY =
+            PiActionId.of("FabricIngress.filtering.deny");
+    public static final PiActionId FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_SET_SESSION =
+            PiActionId.of("FabricIngress.bng_ingress.downstream.set_session");
+    public static final PiActionId FABRIC_INGRESS_NEXT_SET_MCAST_GROUP_ID =
+            PiActionId.of("FabricIngress.next.set_mcast_group_id");
+    public static final PiActionId FABRIC_INGRESS_FILTERING_SET_FORWARDING_TYPE =
+            PiActionId.of("FabricIngress.filtering.set_forwarding_type");
+    public static final PiActionId FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_REPORT_DO_REPORT_ENCAPSULATION =
+            PiActionId.of("FabricEgress.process_int_main.process_int_report.do_report_encapsulation");
+    public static final PiActionId NO_ACTION = PiActionId.of("NoAction");
+    public static final PiActionId FABRIC_INGRESS_NEXT_OUTPUT_XCONNECT =
+            PiActionId.of("FabricIngress.next.output_xconnect");
+    // Action Param IDs
+    public static final PiActionParamId DMAC = PiActionParamId.of("dmac");
+    public static final PiActionParamId MON_PORT =
+            PiActionParamId.of("mon_port");
+    public static final PiActionParamId S1U_SGW_ADDR =
+            PiActionParamId.of("s1u_sgw_addr");
+    public static final PiActionParamId SMAC = PiActionParamId.of("smac");
+    public static final PiActionParamId CLONE_ID =
+            PiActionParamId.of("clone_id");
+    public static final PiActionParamId VLAN_ID = PiActionParamId.of("vlan_id");
+    public static final PiActionParamId LABEL = PiActionParamId.of("label");
+    public static final PiActionParamId SRC_IP = PiActionParamId.of("src_ip");
+    public static final PiActionParamId NEXT_ID = PiActionParamId.of("next_id");
+    public static final PiActionParamId INS_CNT = PiActionParamId.of("ins_cnt");
+    public static final PiActionParamId SRC_MAC = PiActionParamId.of("src_mac");
+    public static final PiActionParamId INNER_VLAN_ID =
+            PiActionParamId.of("inner_vlan_id");
+    public static final PiActionParamId PPPOE_SESSION_ID =
+            PiActionParamId.of("pppoe_session_id");
+    public static final PiActionParamId MON_MAC = PiActionParamId.of("mon_mac");
+    public static final PiActionParamId MON_IP = PiActionParamId.of("mon_ip");
+    public static final PiActionParamId SWITCH_ID =
+            PiActionParamId.of("switch_id");
+    public static final PiActionParamId INS_MASK0003 =
+            PiActionParamId.of("ins_mask0003");
+    public static final PiActionParamId LINE_ID = PiActionParamId.of("line_id");
+    public static final PiActionParamId FWD_TYPE =
+            PiActionParamId.of("fwd_type");
+    public static final PiActionParamId OUTER_VLAN_ID =
+            PiActionParamId.of("outer_vlan_id");
+    public static final PiActionParamId INS_MASK0407 =
+            PiActionParamId.of("ins_mask0407");
+    public static final PiActionParamId TEID = PiActionParamId.of("teid");
+    public static final PiActionParamId S1U_ENB_ADDR =
+            PiActionParamId.of("s1u_enb_addr");
+    public static final PiActionParamId PORT_NUM =
+            PiActionParamId.of("port_num");
+    public static final PiActionParamId GROUP_ID =
+            PiActionParamId.of("group_id");
+    public static final PiActionParamId MAX_HOP = PiActionParamId.of("max_hop");
+    // Action Profile IDs
+    public static final PiActionProfileId FABRIC_INGRESS_NEXT_HASHED_SELECTOR =
+            PiActionProfileId.of("FabricIngress.next.hashed_selector");
+    // Packet Metadata IDs
+    public static final PiPacketMetadataId INGRESS_PORT =
+            PiPacketMetadataId.of("ingress_port");
+    public static final PiPacketMetadataId EGRESS_PORT =
+            PiPacketMetadataId.of("egress_port");
+    // Meter IDs
+    public static final PiMeterId FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_M_BESTEFF =
+            PiMeterId.of("FabricIngress.bng_ingress.downstream.m_besteff");
+    public static final PiMeterId FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_M_PRIO =
+            PiMeterId.of("FabricIngress.bng_ingress.downstream.m_prio");
+}
\ No newline at end of file
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricIntProgrammable.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricIntProgrammable.java
new file mode 100644
index 0000000..4fc8286
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricIntProgrammable.java
@@ -0,0 +1,501 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour;
+
+import com.google.common.collect.Sets;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.inbandtelemetry.api.IntConfig;
+import org.onosproject.inbandtelemetry.api.IntIntent;
+import org.onosproject.inbandtelemetry.api.IntObjective;
+import org.onosproject.inbandtelemetry.api.IntProgrammable;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.device.DeviceService;
+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.FlowRuleService;
+import org.onosproject.net.flow.TableId;
+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.IPCriterion;
+import org.onosproject.net.flow.criteria.PiCriterion;
+import org.onosproject.net.flow.criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.UdpPortCriterion;
+import org.onosproject.net.pi.model.PiTableId;
+import org.onosproject.net.pi.runtime.PiAction;
+import org.onosproject.net.pi.runtime.PiActionParam;
+import org.onosproject.pipelines.fabric.impl.FabricPipeconfLoader;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import static org.onlab.util.ImmutableByteSequence.copyFrom;
+
+/**
+ * Implementation of INT programmable behavior for fabric.p4. Currently supports
+ * only SOURCE and TRANSIT functionalities.
+ */
+public class FabricIntProgrammable extends AbstractFabricHandlerBehavior
+        implements IntProgrammable {
+
+    // TODO: change this value to the value of diameter of a network.
+    private static final int DEFAULT_PRIORITY = 10000;
+    private static final int MAXHOP = 64;
+    private static final int PORTMASK = 0xffff;
+    private static final int PKT_INSTANCE_TYPE_INGRESS_CLONE = 1;
+
+    private static final Set<Criterion.Type> SUPPORTED_CRITERION = Sets.newHashSet(
+            Criterion.Type.IPV4_DST, Criterion.Type.IPV4_SRC,
+            Criterion.Type.UDP_SRC, Criterion.Type.UDP_DST,
+            Criterion.Type.TCP_SRC, Criterion.Type.TCP_DST,
+            Criterion.Type.IP_PROTO);
+
+    private static final Set<PiTableId> TABLES_TO_CLEANUP = Sets.newHashSet(
+            FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_TRANSIT_TB_INT_INSERT,
+            FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SOURCE,
+            FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SINK,
+            FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_TB_INT_SOURCE,
+            FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_REPORT_TB_GENERATE_REPORT
+    );
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    private FlowRuleService flowRuleService;
+
+    private CoreService coreService;
+    private NetworkConfigService cfgService;
+    private DeviceId deviceId;
+    private ApplicationId appId;
+
+    /**
+     * Creates a new instance of this behavior with the given capabilities.
+     *
+     * @param capabilities capabilities
+     */
+    protected FabricIntProgrammable(FabricCapabilities capabilities) {
+        super(capabilities);
+    }
+
+    /**
+     * Create a new instance of this behaviour. Used by the abstract projectable
+     * model (i.e., {@link org.onosproject.net.Device#as(Class)}.
+     */
+    public FabricIntProgrammable() {
+        super();
+    }
+
+    private boolean setupBehaviour() {
+        deviceId = this.data().deviceId();
+        flowRuleService = handler().get(FlowRuleService.class);
+        coreService = handler().get(CoreService.class);
+        cfgService = handler().get(NetworkConfigService.class);
+        appId = coreService.getAppId(FabricPipeconfLoader.PIPELINE_APP_NAME);
+        if (appId == null) {
+            log.warn("Application ID is null. Cannot initialize behaviour.");
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean init() {
+
+        if (!setupBehaviour()) {
+            return false;
+        }
+
+        // FIXME: create config class for INT to allow specifying arbitrary
+        //  switch IDs. The one for the GeneralDeviceProvider was temporary and
+        //  now has been removed. For now we use the chassis ID.
+        // final GeneralProviderDeviceConfig cfg = cfgService.getConfig(
+        //         deviceId, GeneralProviderDeviceConfig.class);
+        // if (cfg == null) {
+        //     log.warn("Missing GeneralProviderDevice config for {}", deviceId);
+        //     return false;
+        // }
+        // final String switchId = cfg.protocolsInfo().containsKey("int") ?
+        //         cfg.protocolsInfo().get("int").configValues().get("switchId")
+        //         : null;
+        // if (switchId == null || switchId.isEmpty()) {
+        //     log.warn("Missing INT device config for {}", deviceId);
+        //     return false;
+        // }
+
+        PiActionParam transitIdParam = new PiActionParam(
+                FabricConstants.SWITCH_ID,
+                copyFrom(handler().get(DeviceService.class)
+                                 .getDevice(deviceId).chassisId().id()));
+
+        PiAction transitAction = PiAction.builder()
+                .withId(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_TRANSIT_INIT_METADATA)
+                .withParameter(transitIdParam)
+                .build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .piTableAction(transitAction)
+                .build();
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchPi(PiCriterion.builder().matchExact(
+                        FabricConstants.HDR_INT_IS_VALID, (byte) 0x01)
+                                 .build())
+                .build();
+
+        FlowRule transitFlowRule = DefaultFlowRule.builder()
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .fromApp(appId)
+                .withPriority(DEFAULT_PRIORITY)
+                .makePermanent()
+                .forDevice(deviceId)
+                .forTable(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_TRANSIT_TB_INT_INSERT)
+                .build();
+
+        flowRuleService.applyFlowRules(transitFlowRule);
+        return true;
+    }
+
+    @Override
+    public boolean setSourcePort(PortNumber port) {
+
+        if (!setupBehaviour()) {
+            return false;
+        }
+
+        PiCriterion ingressCriterion = PiCriterion.builder()
+                .matchExact(FabricConstants.HDR_IG_PORT, port.toLong())
+                .build();
+        TrafficSelector srcSelector = DefaultTrafficSelector.builder()
+                .matchPi(ingressCriterion)
+                .build();
+        PiAction setSourceAct = PiAction.builder()
+                .withId(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_INT_SET_SOURCE)
+                .build();
+        TrafficTreatment srcTreatment = DefaultTrafficTreatment.builder()
+                .piTableAction(setSourceAct)
+                .build();
+        FlowRule srcFlowRule = DefaultFlowRule.builder()
+                .withSelector(srcSelector)
+                .withTreatment(srcTreatment)
+                .fromApp(appId)
+                .withPriority(DEFAULT_PRIORITY)
+                .makePermanent()
+                .forDevice(deviceId)
+                .forTable(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SOURCE)
+                .build();
+        flowRuleService.applyFlowRules(srcFlowRule);
+        return true;
+    }
+
+    @Override
+    public boolean setSinkPort(PortNumber port) {
+
+        if (!setupBehaviour()) {
+            return false;
+        }
+
+        PiCriterion egressCriterion = PiCriterion.builder()
+                .matchExact(FabricConstants.HDR_EG_PORT, port.toLong())
+                .build();
+        TrafficSelector sinkSelector = DefaultTrafficSelector.builder()
+                .matchPi(egressCriterion)
+                .build();
+        PiAction setSinkAct = PiAction.builder()
+                .withId(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_INT_SET_SINK)
+                .build();
+        TrafficTreatment sinkTreatment = DefaultTrafficTreatment.builder()
+                .piTableAction(setSinkAct)
+                .build();
+        FlowRule sinkFlowRule = DefaultFlowRule.builder()
+                .withSelector(sinkSelector)
+                .withTreatment(sinkTreatment)
+                .fromApp(appId)
+                .withPriority(DEFAULT_PRIORITY)
+                .makePermanent()
+                .forDevice(deviceId)
+                .forTable(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SINK)
+                .build();
+        flowRuleService.applyFlowRules(sinkFlowRule);
+        return true;
+    }
+
+    @Override
+    public boolean addIntObjective(IntObjective obj) {
+
+        if (!setupBehaviour()) {
+            return false;
+        }
+
+        return processIntObjective(obj, true);
+    }
+
+    @Override
+    public boolean removeIntObjective(IntObjective obj) {
+
+        if (!setupBehaviour()) {
+            return false;
+        }
+
+        return processIntObjective(obj, false);
+    }
+
+    @Override
+    public boolean setupIntConfig(IntConfig config) {
+
+        if (!setupBehaviour()) {
+            return false;
+        }
+
+        return setupIntReportInternal(config);
+    }
+
+    @Override
+    public void cleanup() {
+
+        if (!setupBehaviour()) {
+            return;
+        }
+
+        StreamSupport.stream(flowRuleService.getFlowEntries(
+                data().deviceId()).spliterator(), false)
+                .filter(f -> f.table().type() == TableId.Type.PIPELINE_INDEPENDENT)
+                .filter(f -> TABLES_TO_CLEANUP.contains((PiTableId) f.table()))
+                .forEach(flowRuleService::removeFlowRules);
+    }
+
+    @Override
+    public boolean supportsFunctionality(IntFunctionality functionality) {
+        // Sink not fully supported yet.
+        return functionality == IntFunctionality.SOURCE || functionality == IntFunctionality.TRANSIT;
+    }
+
+    private FlowRule buildWatchlistEntry(IntObjective obj) {
+        int instructionBitmap = buildInstructionBitmap(obj.metadataTypes());
+        PiActionParam maxHopParam = new PiActionParam(
+                FabricConstants.MAX_HOP,
+                copyFrom(MAXHOP));
+        PiActionParam instCntParam = new PiActionParam(
+                FabricConstants.INS_CNT,
+                copyFrom(Integer.bitCount(instructionBitmap)));
+        PiActionParam inst0003Param = new PiActionParam(
+                FabricConstants.INS_MASK0003,
+                copyFrom((instructionBitmap >> 12) & 0xF));
+        PiActionParam inst0407Param = new PiActionParam(
+                FabricConstants.INS_MASK0407,
+                copyFrom((instructionBitmap >> 8) & 0xF));
+
+        PiAction intSourceAction = PiAction.builder()
+                .withId(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_INT_SOURCE_DSCP)
+                .withParameter(maxHopParam)
+                .withParameter(instCntParam)
+                .withParameter(inst0003Param)
+                .withParameter(inst0407Param)
+                .build();
+
+        TrafficTreatment instTreatment = DefaultTrafficTreatment.builder()
+                .piTableAction(intSourceAction)
+                .build();
+
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        for (Criterion criterion : obj.selector().criteria()) {
+            switch (criterion.type()) {
+                case IPV4_SRC:
+                    sBuilder.matchIPSrc(((IPCriterion) criterion).ip());
+                    break;
+                case IPV4_DST:
+                    sBuilder.matchIPDst(((IPCriterion) criterion).ip());
+                    break;
+                case TCP_SRC:
+                    sBuilder.matchPi(
+                            PiCriterion.builder().matchTernary(
+                                    FabricConstants.HDR_L4_SPORT,
+                                    ((TcpPortCriterion) criterion).tcpPort().toInt(), PORTMASK)
+                                    .build());
+                    break;
+                case UDP_SRC:
+                    sBuilder.matchPi(
+                            PiCriterion.builder().matchTernary(
+                                    FabricConstants.HDR_L4_SPORT,
+                                    ((UdpPortCriterion) criterion).udpPort().toInt(), PORTMASK)
+                                    .build());
+                    break;
+                case TCP_DST:
+                    sBuilder.matchPi(
+                            PiCriterion.builder().matchTernary(
+                                    FabricConstants.HDR_L4_DPORT,
+                                    ((TcpPortCriterion) criterion).tcpPort().toInt(), PORTMASK)
+                                    .build());
+                    break;
+                case UDP_DST:
+                    sBuilder.matchPi(
+                            PiCriterion.builder().matchTernary(
+                                    FabricConstants.HDR_L4_DPORT,
+                                    ((UdpPortCriterion) criterion).udpPort().toInt(), PORTMASK)
+                                    .build());
+                    break;
+                default:
+                    log.warn("Unsupported criterion type: {}", criterion.type());
+            }
+        }
+
+        return DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(sBuilder.build())
+                .withTreatment(instTreatment)
+                .withPriority(DEFAULT_PRIORITY)
+                .forTable(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_TB_INT_SOURCE)
+                .fromApp(appId)
+                .makePermanent()
+                .build();
+    }
+
+    private int buildInstructionBitmap(Set<IntIntent.IntMetadataType> metadataTypes) {
+        int instBitmap = 0;
+        for (IntIntent.IntMetadataType metadataType : metadataTypes) {
+            switch (metadataType) {
+                case SWITCH_ID:
+                    instBitmap |= (1 << 15);
+                    break;
+                case L1_PORT_ID:
+                    instBitmap |= (1 << 14);
+                    break;
+                case HOP_LATENCY:
+                    instBitmap |= (1 << 13);
+                    break;
+                case QUEUE_OCCUPANCY:
+                    instBitmap |= (1 << 12);
+                    break;
+                case INGRESS_TIMESTAMP:
+                    instBitmap |= (1 << 11);
+                    break;
+                case EGRESS_TIMESTAMP:
+                    instBitmap |= (1 << 10);
+                    break;
+                case L2_PORT_ID:
+                    instBitmap |= (1 << 9);
+                    break;
+                case EGRESS_TX_UTIL:
+                    instBitmap |= (1 << 8);
+                    break;
+                default:
+                    log.info("Unsupported metadata type {}. Ignoring...", metadataType);
+                    break;
+            }
+        }
+        return instBitmap;
+    }
+
+    /**
+     * Returns a subset of Criterion from given selector, which is unsupported
+     * by this INT pipeline.
+     *
+     * @param selector a traffic selector
+     * @return a subset of Criterion from given selector, unsupported by this
+     * INT pipeline, empty if all criteria are supported.
+     */
+    private Set<Criterion> unsupportedSelectors(TrafficSelector selector) {
+        return selector.criteria().stream()
+                .filter(criterion -> !SUPPORTED_CRITERION.contains(criterion.type()))
+                .collect(Collectors.toSet());
+    }
+
+    private boolean processIntObjective(IntObjective obj, boolean install) {
+        if (install && !unsupportedSelectors(obj.selector()).isEmpty()) {
+            log.warn("Criteria {} not supported by {} for INT watchlist",
+                     unsupportedSelectors(obj.selector()), deviceId);
+            return false;
+        }
+
+        FlowRule flowRule = buildWatchlistEntry(obj);
+        if (flowRule != null) {
+            if (install) {
+                flowRuleService.applyFlowRules(flowRule);
+            } else {
+                flowRuleService.removeFlowRules(flowRule);
+            }
+            log.debug("IntObjective {} has been {} {}",
+                      obj, install ? "installed to" : "removed from", deviceId);
+            return true;
+        } else {
+            log.warn("Failed to {} IntObjective {} on {}",
+                     install ? "install" : "remove", obj, deviceId);
+            return false;
+        }
+    }
+
+    private boolean setupIntReportInternal(IntConfig cfg) {
+        // Report not fully supported yet.
+        return true;
+        // FlowRule reportRule = buildReportEntry(cfg, PKT_INSTANCE_TYPE_INGRESS_CLONE);
+        // if (reportRule != null) {
+        //     flowRuleService.applyFlowRules(reportRule);
+        //     log.info("Report entry {} has been added to {}", reportRule, this.data().deviceId());
+        //     return true;
+        // } else {
+        //     log.warn("Failed to add report entry on {}", this.data().deviceId());
+        //     return false;
+        // }
+    }
+
+    private FlowRule buildReportEntry(IntConfig cfg, int type) {
+
+        if (!setupBehaviour()) {
+            return null;
+        }
+
+        PiActionParam srcMacParam = new PiActionParam(
+                FabricConstants.SRC_MAC,
+                copyFrom(cfg.sinkMac().toBytes()));
+        PiActionParam nextHopMacParam = new PiActionParam(
+                FabricConstants.MON_MAC,
+                copyFrom(cfg.collectorNextHopMac().toBytes()));
+        PiActionParam srcIpParam = new PiActionParam(
+                FabricConstants.SRC_IP,
+                copyFrom(cfg.sinkIp().toOctets()));
+        PiActionParam monIpParam = new PiActionParam(
+                FabricConstants.MON_IP,
+                copyFrom(cfg.collectorIp().toOctets()));
+        PiActionParam monPortParam = new PiActionParam(
+                FabricConstants.MON_PORT,
+                copyFrom(cfg.collectorPort().toInt()));
+        PiAction reportAction = PiAction.builder()
+                .withId(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_REPORT_DO_REPORT_ENCAPSULATION)
+                .withParameter(srcMacParam)
+                .withParameter(nextHopMacParam)
+                .withParameter(srcIpParam)
+                .withParameter(monIpParam)
+                .withParameter(monPortParam)
+                .build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .piTableAction(reportAction)
+                .build();
+
+        return DefaultFlowRule.builder()
+                .withTreatment(treatment)
+                .fromApp(appId)
+                .withPriority(DEFAULT_PRIORITY)
+                .makePermanent()
+                .forDevice(this.data().deviceId())
+                .forTable(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_REPORT_TB_GENERATE_REPORT)
+                .build();
+    }
+
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricInterpreter.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricInterpreter.java
new file mode 100644
index 0000000..816c0dd
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricInterpreter.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.Ethernet;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.pi.model.PiMatchFieldId;
+import org.onosproject.net.pi.model.PiPipelineInterpreter;
+import org.onosproject.net.pi.model.PiTableId;
+import org.onosproject.net.pi.runtime.PiAction;
+import org.onosproject.net.pi.runtime.PiPacketMetadata;
+import org.onosproject.net.pi.runtime.PiPacketOperation;
+
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import static java.lang.String.format;
+import static java.util.stream.Collectors.toList;
+import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.PortNumber.CONTROLLER;
+import static org.onosproject.net.PortNumber.FLOOD;
+import static org.onosproject.net.flow.instructions.Instruction.Type.OUTPUT;
+import static org.onosproject.net.pi.model.PiPacketOperationType.PACKET_OUT;
+
+/**
+ * Interpreter for fabric pipeline.
+ */
+public class FabricInterpreter extends AbstractFabricHandlerBehavior
+        implements PiPipelineInterpreter {
+
+    private static final int PORT_BITWIDTH = 9;
+
+    // Group tables by control block.
+    private static final Set<PiTableId> FILTERING_CTRL_TBLS = ImmutableSet.of(
+            FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN,
+            FabricConstants.FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER);
+    private static final Set<PiTableId> FORWARDING_CTRL_TBLS = ImmutableSet.of(
+            FabricConstants.FABRIC_INGRESS_FORWARDING_MPLS,
+            FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
+            FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V6,
+            FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING);
+    private static final Set<PiTableId> ACL_CTRL_TBLS = ImmutableSet.of(
+            FabricConstants.FABRIC_INGRESS_ACL_ACL);
+    private static final Set<PiTableId> NEXT_CTRL_TBLS = ImmutableSet.of(
+            FabricConstants.FABRIC_INGRESS_NEXT_NEXT_VLAN,
+            FabricConstants.FABRIC_INGRESS_NEXT_SIMPLE,
+            FabricConstants.FABRIC_INGRESS_NEXT_HASHED,
+            FabricConstants.FABRIC_INGRESS_NEXT_XCONNECT);
+    private static final Set<PiTableId> E_NEXT_CTRL_TBLS = ImmutableSet.of(
+            FabricConstants.FABRIC_EGRESS_EGRESS_NEXT_EGRESS_VLAN);
+
+    private static final ImmutableMap<Criterion.Type, PiMatchFieldId> CRITERION_MAP =
+            ImmutableMap.<Criterion.Type, PiMatchFieldId>builder()
+                    .put(Criterion.Type.IN_PORT, FabricConstants.HDR_IG_PORT)
+                    .put(Criterion.Type.ETH_DST, FabricConstants.HDR_ETH_DST)
+                    .put(Criterion.Type.ETH_SRC, FabricConstants.HDR_ETH_SRC)
+                    .put(Criterion.Type.ETH_DST_MASKED, FabricConstants.HDR_ETH_DST)
+                    .put(Criterion.Type.ETH_SRC_MASKED, FabricConstants.HDR_ETH_SRC)
+                    .put(Criterion.Type.ETH_TYPE, FabricConstants.HDR_ETH_TYPE)
+                    .put(Criterion.Type.MPLS_LABEL, FabricConstants.HDR_MPLS_LABEL)
+                    .put(Criterion.Type.VLAN_VID, FabricConstants.HDR_VLAN_ID)
+                    .put(Criterion.Type.INNER_VLAN_VID, FabricConstants.HDR_INNER_VLAN_ID)
+                    .put(Criterion.Type.IPV4_DST, FabricConstants.HDR_IPV4_DST)
+                    .put(Criterion.Type.IPV4_SRC, FabricConstants.HDR_IPV4_SRC)
+                    .put(Criterion.Type.IPV6_DST, FabricConstants.HDR_IPV6_DST)
+                    .put(Criterion.Type.IP_PROTO, FabricConstants.HDR_IP_PROTO)
+                    .put(Criterion.Type.ICMPV6_TYPE, FabricConstants.HDR_ICMP_TYPE)
+                    .put(Criterion.Type.ICMPV6_CODE, FabricConstants.HDR_ICMP_CODE)
+                    .put(Criterion.Type.UDP_DST, FabricConstants.HDR_L4_DPORT)
+                    .put(Criterion.Type.UDP_SRC, FabricConstants.HDR_L4_SPORT)
+                    .put(Criterion.Type.UDP_DST_MASKED, FabricConstants.HDR_L4_DPORT)
+                    .put(Criterion.Type.UDP_SRC_MASKED, FabricConstants.HDR_L4_SPORT)
+                    .put(Criterion.Type.TCP_DST, FabricConstants.HDR_L4_DPORT)
+                    .put(Criterion.Type.TCP_SRC, FabricConstants.HDR_L4_SPORT)
+                    .put(Criterion.Type.TCP_DST_MASKED, FabricConstants.HDR_L4_DPORT)
+                    .put(Criterion.Type.TCP_SRC_MASKED, FabricConstants.HDR_L4_SPORT)
+                    .build();
+
+    private static final PiAction NOP = PiAction.builder()
+            .withId(FabricConstants.NOP).build();
+
+    private static final ImmutableMap<PiTableId, PiAction> DEFAULT_ACTIONS =
+            ImmutableMap.<PiTableId, PiAction>builder()
+                    .put(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4, NOP)
+                    .build();
+
+    private FabricTreatmentInterpreter treatmentInterpreter;
+
+    /**
+     * Creates a new instance of this behavior with the given capabilities.
+     *
+     * @param capabilities capabilities
+     */
+    public FabricInterpreter(FabricCapabilities capabilities) {
+        super(capabilities);
+        instantiateTreatmentInterpreter();
+    }
+
+    /**
+     * Create a new instance of this behaviour. Used by the abstract projectable
+     * model (i.e., {@link org.onosproject.net.Device#as(Class)}.
+     */
+    public FabricInterpreter() {
+        super();
+    }
+
+    private void instantiateTreatmentInterpreter() {
+        this.treatmentInterpreter = new FabricTreatmentInterpreter(this.capabilities);
+    }
+
+    @Override
+    public void setHandler(DriverHandler handler) {
+        super.setHandler(handler);
+        instantiateTreatmentInterpreter();
+    }
+
+    @Override
+    public Optional<PiMatchFieldId> mapCriterionType(Criterion.Type type) {
+        return Optional.ofNullable(CRITERION_MAP.get(type));
+    }
+
+    @Override
+    public Optional<PiTableId> mapFlowRuleTableId(int flowRuleTableId) {
+        // The only use case for Index ID->PiTableId is when using the single
+        // table pipeliner. fabric.p4 is never used with such pipeliner.
+        return Optional.empty();
+    }
+
+    @Override
+    public PiAction mapTreatment(TrafficTreatment treatment, PiTableId piTableId)
+            throws PiInterpreterException {
+        if (FILTERING_CTRL_TBLS.contains(piTableId)) {
+            return treatmentInterpreter.mapFilteringTreatment(treatment, piTableId);
+        } else if (FORWARDING_CTRL_TBLS.contains(piTableId)) {
+            return treatmentInterpreter.mapForwardingTreatment(treatment, piTableId);
+        } else if (ACL_CTRL_TBLS.contains(piTableId)) {
+            return treatmentInterpreter.mapAclTreatment(treatment, piTableId);
+        } else if (NEXT_CTRL_TBLS.contains(piTableId)) {
+            return treatmentInterpreter.mapNextTreatment(treatment, piTableId);
+        } else if (E_NEXT_CTRL_TBLS.contains(piTableId)) {
+            return treatmentInterpreter.mapEgressNextTreatment(treatment, piTableId);
+        } else {
+            throw new PiInterpreterException(format(
+                    "Treatment mapping not supported for table '%s'", piTableId));
+        }
+    }
+
+    private PiPacketOperation createPiPacketOperation(
+            DeviceId deviceId, ByteBuffer data, long portNumber)
+            throws PiInterpreterException {
+        PiPacketMetadata metadata = createPacketMetadata(portNumber);
+        return PiPacketOperation.builder()
+                .withType(PACKET_OUT)
+                .withData(copyFrom(data))
+                .withMetadatas(ImmutableList.of(metadata))
+                .build();
+    }
+
+    private PiPacketMetadata createPacketMetadata(long portNumber)
+            throws PiInterpreterException {
+        try {
+            return PiPacketMetadata.builder()
+                    .withId(FabricConstants.EGRESS_PORT)
+                    .withValue(copyFrom(portNumber).fit(PORT_BITWIDTH))
+                    .build();
+        } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
+            throw new PiInterpreterException(format(
+                    "Port number '%d' too big, %s", portNumber, e.getMessage()));
+        }
+    }
+
+    @Override
+    public Collection<PiPacketOperation> mapOutboundPacket(OutboundPacket packet)
+            throws PiInterpreterException {
+        DeviceId deviceId = packet.sendThrough();
+        TrafficTreatment treatment = packet.treatment();
+
+        // fabric.p4 supports only OUTPUT instructions.
+        List<Instructions.OutputInstruction> outInstructions = treatment
+                .allInstructions()
+                .stream()
+                .filter(i -> i.type().equals(OUTPUT))
+                .map(i -> (Instructions.OutputInstruction) i)
+                .collect(toList());
+
+        if (treatment.allInstructions().size() != outInstructions.size()) {
+            // There are other instructions that are not of type OUTPUT.
+            throw new PiInterpreterException("Treatment not supported: " + treatment);
+        }
+
+        ImmutableList.Builder<PiPacketOperation> builder = ImmutableList.builder();
+        for (Instructions.OutputInstruction outInst : outInstructions) {
+            if (outInst.port().isLogical() && !outInst.port().equals(FLOOD)) {
+                throw new PiInterpreterException(format(
+                        "Output on logical port '%s' not supported", outInst.port()));
+            } else if (outInst.port().equals(FLOOD)) {
+                // Since fabric.p4 does not support flooding, we create a packet
+                // operation for each switch port.
+                final DeviceService deviceService = handler().get(DeviceService.class);
+                for (Port port : deviceService.getPorts(packet.sendThrough())) {
+                    builder.add(createPiPacketOperation(deviceId, packet.data(), port.number().toLong()));
+                }
+            } else {
+                builder.add(createPiPacketOperation(deviceId, packet.data(), outInst.port().toLong()));
+            }
+        }
+        return builder.build();
+    }
+
+    @Override
+    public InboundPacket mapInboundPacket(PiPacketOperation packetIn, DeviceId deviceId) throws PiInterpreterException {
+        // Assuming that the packet is ethernet, which is fine since fabric.p4
+        // can deparse only ethernet packets.
+        Ethernet ethPkt;
+        try {
+            ethPkt = Ethernet.deserializer().deserialize(packetIn.data().asArray(), 0,
+                                                         packetIn.data().size());
+        } catch (DeserializationException dex) {
+            throw new PiInterpreterException(dex.getMessage());
+        }
+
+        // Returns the ingress port packet metadata.
+        Optional<PiPacketMetadata> packetMetadata = packetIn.metadatas()
+                .stream().filter(m -> m.id().equals(FabricConstants.INGRESS_PORT))
+                .findFirst();
+
+        if (packetMetadata.isPresent()) {
+            ImmutableByteSequence portByteSequence = packetMetadata.get().value();
+            short s = portByteSequence.asReadOnlyBuffer().getShort();
+            ConnectPoint receivedFrom = new ConnectPoint(deviceId, PortNumber.portNumber(s));
+            ByteBuffer rawData = ByteBuffer.wrap(packetIn.data().asArray());
+            return new DefaultInboundPacket(receivedFrom, ethPkt, rawData);
+        } else {
+            throw new PiInterpreterException(format(
+                    "Missing metadata '%s' in packet-in received from '%s': %s",
+                    FabricConstants.INGRESS_PORT, deviceId, packetIn));
+        }
+    }
+
+    @Override
+    public Optional<PiAction> getOriginalDefaultAction(PiTableId tableId) {
+        return Optional.ofNullable(DEFAULT_ACTIONS.get(tableId));
+    }
+
+    @Override
+    public Optional<Integer> mapLogicalPortNumber(PortNumber port) {
+        if (!port.equals(CONTROLLER)) {
+            return Optional.empty();
+        }
+        return capabilities.cpuPort();
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricPortStatisticsDiscovery.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricPortStatisticsDiscovery.java
new file mode 100644
index 0000000..b461ad3
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricPortStatisticsDiscovery.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour;
+
+
+import org.onosproject.net.pi.model.PiCounterId;
+import org.onosproject.pipelines.basic.PortStatisticsDiscoveryImpl;
+
+/**
+ * Implementation of the PortStatisticsBehaviour for fabric.p4.
+ */
+public class FabricPortStatisticsDiscovery extends PortStatisticsDiscoveryImpl {
+
+    /**
+     * Returns the ID of the ingress port counter.
+     *
+     * @return counter ID
+     */
+    @Override
+    public PiCounterId ingressCounterId() {
+        return FabricConstants.FABRIC_INGRESS_PORT_COUNTERS_CONTROL_INGRESS_PORT_COUNTER;
+    }
+
+    /**
+     * Returns the ID of the egress port counter.
+     *
+     * @return counter ID
+     */
+    @Override
+    public PiCounterId egressCounterId() {
+        return FabricConstants.FABRIC_INGRESS_PORT_COUNTERS_CONTROL_EGRESS_PORT_COUNTER;
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricTreatmentInterpreter.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricTreatmentInterpreter.java
new file mode 100644
index 0000000..78ef9a7
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricTreatmentInterpreter.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour;
+
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
+import org.onosproject.net.pi.model.PiActionId;
+import org.onosproject.net.pi.model.PiPipelineInterpreter.PiInterpreterException;
+import org.onosproject.net.pi.model.PiTableId;
+import org.onosproject.net.pi.runtime.PiAction;
+import org.onosproject.net.pi.runtime.PiActionParam;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+import static org.onosproject.net.flow.instructions.Instruction.Type.OUTPUT;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.ETH_DST;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.ETH_SRC;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.MPLS_LABEL;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.MPLS_PUSH;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_ID;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_POP;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.instruction;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.l2Instruction;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.l2Instructions;
+
+/**
+ * Treatment translation logic.
+ */
+final class FabricTreatmentInterpreter {
+
+    private final FabricCapabilities capabilities;
+    private static final ImmutableMap<PiTableId, PiActionId> NOP_ACTIONS =
+            ImmutableMap.<PiTableId, PiActionId>builder()
+                    .put(FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN,
+                         FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT)
+                    .put(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
+                         FabricConstants.FABRIC_INGRESS_FORWARDING_NOP_ROUTING_V4)
+                    .put(FabricConstants.FABRIC_INGRESS_ACL_ACL,
+                         FabricConstants.FABRIC_INGRESS_ACL_NOP_ACL)
+                    .put(FabricConstants.FABRIC_EGRESS_EGRESS_NEXT_EGRESS_VLAN,
+                         FabricConstants.FABRIC_EGRESS_EGRESS_NEXT_POP_VLAN)
+                    .build();
+
+
+    FabricTreatmentInterpreter(FabricCapabilities capabilities) {
+        this.capabilities = capabilities;
+    }
+
+    static PiAction mapFilteringTreatment(TrafficTreatment treatment, PiTableId tableId)
+            throws PiInterpreterException {
+
+        if (!tableId.equals(FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)) {
+            // Mapping for other tables of the filtering block must be handled
+            // in the pipeliner.
+            tableException(tableId);
+        }
+
+        // VLAN_POP action is equivalent to the permit action (VLANs pop is done anyway)
+        if (isNoAction(treatment) || isFilteringPopAction(treatment)) {
+            // Permit action if table is ingress_port_vlan;
+            return nop(tableId);
+        }
+
+        final ModVlanIdInstruction setVlanInst = (ModVlanIdInstruction) l2InstructionOrFail(
+                treatment, VLAN_ID, tableId);
+        return PiAction.builder()
+                .withId(FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT_WITH_INTERNAL_VLAN)
+                .withParameter(new PiActionParam(
+                        FabricConstants.VLAN_ID, setVlanInst.vlanId().toShort()))
+                .build();
+    }
+
+
+    static PiAction mapForwardingTreatment(TrafficTreatment treatment, PiTableId tableId)
+            throws PiInterpreterException {
+        if (isNoAction(treatment)) {
+            return nop(tableId);
+        }
+        treatmentException(
+                tableId, treatment,
+                "supports mapping only for empty/no-action treatments");
+        return null;
+    }
+
+    PiAction mapNextTreatment(TrafficTreatment treatment, PiTableId tableId)
+            throws PiInterpreterException {
+        if (tableId == FabricConstants.FABRIC_INGRESS_NEXT_NEXT_VLAN) {
+            return mapNextVlanTreatment(treatment, tableId);
+        } else if (tableId == FabricConstants.FABRIC_INGRESS_NEXT_HASHED) {
+            return mapNextHashedOrSimpleTreatment(treatment, tableId, false);
+        } else if (tableId == FabricConstants.FABRIC_INGRESS_NEXT_SIMPLE) {
+            return mapNextHashedOrSimpleTreatment(treatment, tableId, true);
+        } else if (tableId == FabricConstants.FABRIC_INGRESS_NEXT_XCONNECT) {
+            return mapNextXconnect(treatment, tableId);
+        }
+        throw new PiInterpreterException(format(
+                "Treatment mapping not supported for table '%s'", tableId));
+    }
+
+    private PiAction mapNextVlanTreatment(TrafficTreatment treatment, PiTableId tableId)
+            throws PiInterpreterException {
+        final List<ModVlanIdInstruction> modVlanIdInst = l2InstructionsOrFail(treatment, VLAN_ID, tableId)
+                .stream().map(i -> (ModVlanIdInstruction) i).collect(Collectors.toList());
+        if (modVlanIdInst.size() == 1) {
+            return PiAction.builder().withId(FabricConstants.FABRIC_INGRESS_NEXT_SET_VLAN)
+                    .withParameter(new PiActionParam(
+                            FabricConstants.VLAN_ID,
+                            modVlanIdInst.get(0).vlanId().toShort()))
+                    .build();
+        }
+        if (modVlanIdInst.size() == 2 && capabilities.supportDoubleVlanTerm()) {
+            return PiAction.builder()
+                    .withId(FabricConstants.FABRIC_INGRESS_NEXT_SET_DOUBLE_VLAN)
+                    .withParameter(new PiActionParam(
+                            FabricConstants.INNER_VLAN_ID,
+                            modVlanIdInst.get(0).vlanId().toShort()))
+                    .withParameter(new PiActionParam(
+                            FabricConstants.OUTER_VLAN_ID,
+                            modVlanIdInst.get(1).vlanId().toShort()))
+                    .build();
+        }
+        throw new PiInterpreterException("Too many VLAN instructions");
+    }
+
+    private static PiAction mapNextHashedOrSimpleTreatment(
+            TrafficTreatment treatment, PiTableId tableId, boolean simple)
+            throws PiInterpreterException {
+        // Provide mapping for output_hashed, routing_hashed, and
+        // mpls_routing_hashed. multicast_hashed can only be invoked with
+        // PiAction, hence no mapping. outPort required for all actions. Presence
+        // of other instructions will determine which action to map to.
+        final PortNumber outPort = ((OutputInstruction) instructionOrFail(
+                treatment, OUTPUT, tableId)).port();
+        final ModEtherInstruction ethDst = (ModEtherInstruction) l2Instruction(
+                treatment, ETH_DST);
+        final ModEtherInstruction ethSrc = (ModEtherInstruction) l2Instruction(
+                treatment, ETH_SRC);
+        final Instruction mplsPush = l2Instruction(
+                treatment, MPLS_PUSH);
+        final ModMplsLabelInstruction mplsLabel = (ModMplsLabelInstruction) l2Instruction(
+                treatment, MPLS_LABEL);
+
+        final PiAction.Builder actionBuilder = PiAction.builder()
+                .withParameter(new PiActionParam(FabricConstants.PORT_NUM, outPort.toLong()));
+
+        if (ethDst != null && ethSrc != null) {
+            actionBuilder.withParameter(new PiActionParam(
+                    FabricConstants.SMAC, ethSrc.mac().toBytes()));
+            actionBuilder.withParameter(new PiActionParam(
+                    FabricConstants.DMAC, ethDst.mac().toBytes()));
+            if (mplsLabel != null) {
+                // mpls_routing_hashed
+                return actionBuilder
+                        .withParameter(new PiActionParam(FabricConstants.LABEL, mplsLabel.label().toInt()))
+                        .withId(simple ? FabricConstants.FABRIC_INGRESS_NEXT_MPLS_ROUTING_SIMPLE
+                                        : FabricConstants.FABRIC_INGRESS_NEXT_MPLS_ROUTING_HASHED)
+                        .build();
+            } else {
+                // routing_hashed
+                return actionBuilder
+                        .withId(simple ? FabricConstants.FABRIC_INGRESS_NEXT_ROUTING_SIMPLE
+                                        : FabricConstants.FABRIC_INGRESS_NEXT_ROUTING_HASHED)
+                        .build();
+            }
+        } else {
+            // output_hashed
+            return actionBuilder
+                    .withId(simple ? FabricConstants.FABRIC_INGRESS_NEXT_OUTPUT_SIMPLE
+                                    : FabricConstants.FABRIC_INGRESS_NEXT_OUTPUT_HASHED)
+                    .build();
+        }
+    }
+
+    private static PiAction mapNextXconnect(
+            TrafficTreatment treatment, PiTableId tableId)
+            throws PiInterpreterException {
+        final PortNumber outPort = ((OutputInstruction) instructionOrFail(
+                treatment, OUTPUT, tableId)).port();
+        return PiAction.builder()
+                .withId(FabricConstants.FABRIC_INGRESS_NEXT_OUTPUT_XCONNECT)
+                .withParameter(new PiActionParam(
+                        FabricConstants.PORT_NUM, outPort.toLong()))
+                .build();
+    }
+
+    static PiAction mapAclTreatment(TrafficTreatment treatment, PiTableId tableId)
+            throws PiInterpreterException {
+        if (isNoAction(treatment)) {
+            return nop(tableId);
+        }
+        treatmentException(
+                tableId, treatment,
+                "unsupported treatment");
+
+        // This function will never return null
+        return null;
+    }
+
+
+    static PiAction mapEgressNextTreatment(
+            TrafficTreatment treatment, PiTableId tableId)
+            throws PiInterpreterException {
+        l2InstructionOrFail(treatment, VLAN_POP, tableId);
+        return PiAction.builder()
+                .withId(FabricConstants.FABRIC_EGRESS_EGRESS_NEXT_POP_VLAN)
+                .build();
+
+    }
+
+    private static PiAction nop(PiTableId tableId) throws PiInterpreterException {
+        if (!NOP_ACTIONS.containsKey(tableId)) {
+            throw new PiInterpreterException(format("table '%s' doe not specify a nop action", tableId));
+        }
+        return PiAction.builder().withId(NOP_ACTIONS.get(tableId)).build();
+    }
+
+    private static boolean isNoAction(TrafficTreatment treatment) {
+        return treatment.equals(DefaultTrafficTreatment.emptyTreatment()) ||
+                treatment.allInstructions().isEmpty();
+    }
+
+    private static boolean isFilteringPopAction(TrafficTreatment treatment) {
+        return l2Instruction(treatment, VLAN_POP) != null;
+    }
+
+    private static Instruction l2InstructionOrFail(
+            TrafficTreatment treatment,
+            L2ModificationInstruction.L2SubType subType, PiTableId tableId)
+            throws PiInterpreterException {
+        final Instruction inst = l2Instruction(treatment, subType);
+        if (inst == null) {
+            treatmentException(tableId, treatment, format("missing %s instruction", subType));
+        }
+        return inst;
+    }
+
+    private static List<L2ModificationInstruction> l2InstructionsOrFail(
+            TrafficTreatment treatment,
+            L2ModificationInstruction.L2SubType subType, PiTableId tableId)
+            throws PiInterpreterException {
+        final List<L2ModificationInstruction> inst = l2Instructions(treatment, subType);
+        if (inst == null || inst.isEmpty()) {
+            treatmentException(tableId, treatment, format("missing %s instruction", subType));
+        }
+        return inst;
+    }
+
+    private static Instruction instructionOrFail(
+            TrafficTreatment treatment, Instruction.Type type, PiTableId tableId)
+            throws PiInterpreterException {
+        final Instruction inst = instruction(treatment, type);
+        if (inst == null) {
+            treatmentException(tableId, treatment, format("missing %s instruction", type));
+        }
+        return inst;
+    }
+
+    private static void tableException(PiTableId tableId)
+            throws PiInterpreterException {
+        throw new PiInterpreterException(format("Table '%s' not supported", tableId));
+    }
+
+    private static void treatmentException(
+            PiTableId tableId, TrafficTreatment treatment, String explanation)
+            throws PiInterpreterException {
+        throw new PiInterpreterException(format(
+                "Invalid treatment for table '%s', %s: %s", tableId, explanation, treatment));
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricUtils.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricUtils.java
new file mode 100644
index 0000000..655f88d
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricUtils.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour;
+
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flowobjective.DefaultNextTreatment;
+import org.onosproject.net.flowobjective.NextTreatment;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
+
+/**
+ * Utility class with methods common to fabric pipeconf operations.
+ */
+public final class FabricUtils {
+
+    private FabricUtils() {
+        // Hides constructor.
+    }
+
+    public static Criterion criterion(Collection<Criterion> criteria, Criterion.Type type) {
+        return criteria.stream()
+                .filter(c -> c.type().equals(type))
+                .findFirst().orElse(null);
+    }
+
+    public static Criterion criterion(TrafficSelector selector, Criterion.Type type) {
+        return selector.getCriterion(type);
+    }
+
+    public static Criterion criterionNotNull(TrafficSelector selector, Criterion.Type type) {
+        return checkNotNull(criterion(selector, type),
+                            format("%s criterion cannot be null", type));
+    }
+
+    public static Criterion criterionNotNull(Collection<Criterion> criteria, Criterion.Type type) {
+        return checkNotNull(criterion(criteria, type),
+                            format("%s criterion cannot be null", type));
+    }
+
+    public static Instructions.OutputInstruction instruction(TrafficTreatment treatment, Instruction.Type type) {
+        return treatment.allInstructions()
+                .stream()
+                .filter(inst -> inst.type() == type)
+                .map(inst -> (Instructions.OutputInstruction) inst)
+                .findFirst().orElse(null);
+    }
+
+    public static L2ModificationInstruction l2Instruction(
+            TrafficTreatment treatment, L2ModificationInstruction.L2SubType subType) {
+        return treatment.allInstructions().stream()
+                .filter(i -> i.type().equals(Instruction.Type.L2MODIFICATION))
+                .map(i -> (L2ModificationInstruction) i)
+                .filter(i -> i.subtype().equals(subType))
+                .findFirst().orElse(null);
+    }
+
+    public static List<L2ModificationInstruction> l2Instructions(
+            TrafficTreatment treatment, L2ModificationInstruction.L2SubType subType) {
+        return treatment.allInstructions().stream()
+                .filter(i -> i.type().equals(Instruction.Type.L2MODIFICATION))
+                .map(i -> (L2ModificationInstruction) i)
+                .filter(i -> i.subtype().equals(subType))
+                .collect(Collectors.toList());
+    }
+
+    public static Instructions.OutputInstruction outputInstruction(TrafficTreatment treatment) {
+        return instruction(treatment, Instruction.Type.OUTPUT);
+    }
+
+    public static PortNumber outputPort(TrafficTreatment treatment) {
+        final Instructions.OutputInstruction inst = outputInstruction(treatment);
+        return inst == null ? null : inst.port();
+    }
+
+    public static PortNumber outputPort(NextTreatment treatment) {
+        if (treatment.type() == NextTreatment.Type.TREATMENT) {
+            final DefaultNextTreatment t = (DefaultNextTreatment) treatment;
+            return outputPort(t.treatment());
+        }
+        return null;
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/package-info.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/package-info.java
new file mode 100644
index 0000000..75586a1
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * Fabric pipeconf behaviour implementations.
+ */
+package org.onosproject.pipelines.fabric.impl.behaviour;
\ No newline at end of file
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/AbstractObjectiveTranslator.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/AbstractObjectiveTranslator.java
new file mode 100644
index 0000000..5b9671f
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/AbstractObjectiveTranslator.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour.pipeliner;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.DefaultFlowRule;
+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.instructions.Instruction;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.pi.model.PiPipelineInterpreter;
+import org.onosproject.net.pi.model.PiTableId;
+import org.onosproject.net.pi.runtime.PiAction;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricInterpreter;
+import org.slf4j.Logger;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Abstract implementation of a pipeliner logic for the fabric pipeconf.
+ */
+abstract class AbstractObjectiveTranslator<T extends Objective> {
+
+    protected final Logger log = getLogger(this.getClass());
+
+    protected final FabricCapabilities capabilities;
+    protected final DeviceId deviceId;
+
+    private final PiPipelineInterpreter interpreter;
+
+    AbstractObjectiveTranslator(DeviceId deviceId, FabricCapabilities capabilities) {
+        this.deviceId = checkNotNull(deviceId);
+        this.capabilities = checkNotNull(capabilities);
+        this.interpreter = new FabricInterpreter(capabilities);
+    }
+
+    public ObjectiveTranslation translate(T obj) {
+        try {
+            return doTranslate(obj);
+        } catch (FabricPipelinerException e) {
+            log.warn("Cannot translate {}: {} [{}]",
+                     obj.getClass().getSimpleName(), e.getMessage(), obj);
+            return ObjectiveTranslation.ofError(e.objectiveError());
+        }
+    }
+
+    public abstract ObjectiveTranslation doTranslate(T obj)
+            throws FabricPipelinerException;
+
+    public FlowRule flowRule(T obj, PiTableId tableId, TrafficSelector selector,
+                             TrafficTreatment treatment)
+            throws FabricPipelinerException {
+        return DefaultFlowRule.builder()
+                .withSelector(selector)
+                .withTreatment(mapTreatmentToPiIfNeeded(treatment, tableId))
+                .forTable(tableId)
+                .makePermanent()
+                .withPriority(obj.priority())
+                .forDevice(deviceId)
+                .fromApp(obj.appId())
+                .build();
+    }
+
+    TrafficTreatment mapTreatmentToPiIfNeeded(TrafficTreatment treatment, PiTableId tableId)
+            throws FabricPipelinerException {
+        if (isTreatmentPi(treatment)) {
+            return treatment;
+        }
+        final PiAction piAction;
+        try {
+            piAction = interpreter.mapTreatment(treatment, tableId);
+        } catch (PiPipelineInterpreter.PiInterpreterException ex) {
+            throw new FabricPipelinerException(
+                    format("Unable to map treatment for table '%s': %s",
+                           tableId, ex.getMessage()),
+                    ObjectiveError.UNSUPPORTED);
+        }
+        return DefaultTrafficTreatment.builder()
+                .piTableAction(piAction)
+                .build();
+    }
+
+    private boolean isTreatmentPi(TrafficTreatment treatment) {
+        return treatment.allInstructions().size() == 1
+                && treatment.allInstructions().get(0).type() == Instruction.Type.PROTOCOL_INDEPENDENT;
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/Commons.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/Commons.java
new file mode 100644
index 0000000..b288eb4
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/Commons.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour.pipeliner;
+
+import org.onlab.packet.EthType;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
+
+/**
+ * Constants common to ForwardingFunctionType operations.
+ */
+final class Commons {
+
+    static final Criterion MATCH_ETH_TYPE_IPV4 = Criteria.matchEthType(
+      EthType.EtherType.IPV4.ethType());
+    static final Criterion MATCH_ETH_TYPE_IPV6 = Criteria.matchEthType(
+      EthType.EtherType.IPV6.ethType());
+    static final Criterion MATCH_ETH_DST_NONE = Criteria.matchEthDst(
+      MacAddress.NONE);
+    static final Criterion MATCH_ETH_TYPE_MPLS = Criteria.matchEthType(
+      EthType.EtherType.MPLS_UNICAST.ethType());
+    static final Criterion MATCH_MPLS_BOS_TRUE = Criteria.matchMplsBos(true);
+    static final Criterion MATCH_MPLS_BOS_FALSE = Criteria.matchMplsBos(false);
+
+    private Commons() {
+        // hides constructor.
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipeliner.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipeliner.java
new file mode 100644
index 0000000..eac2116
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipeliner.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour.pipeliner;
+
+import com.google.common.collect.ImmutableList;
+import org.onlab.util.KryoNamespace;
+import org.onlab.util.SharedExecutors;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.NextGroup;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.behaviour.PipelinerContext;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveStore;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.IdNextTreatment;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.NextTreatment;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.pipelines.fabric.impl.behaviour.AbstractFabricHandlerBehavior;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.outputPort;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Pipeliner implementation for fabric pipeline which uses ObjectiveTranslator
+ * implementations to translate flow objectives for the different blocks,
+ * filtering, forwarding and next.
+ */
+public class FabricPipeliner extends AbstractFabricHandlerBehavior
+        implements Pipeliner {
+
+    private static final Logger log = getLogger(FabricPipeliner.class);
+
+    protected static final KryoNamespace KRYO = new KryoNamespace.Builder()
+            .register(KryoNamespaces.API)
+            .register(FabricNextGroup.class)
+            .build("FabricPipeliner");
+
+    protected DeviceId deviceId;
+    protected FlowRuleService flowRuleService;
+    protected GroupService groupService;
+    protected FlowObjectiveStore flowObjectiveStore;
+
+    private FilteringObjectiveTranslator filteringTranslator;
+    private ForwardingObjectiveTranslator forwardingTranslator;
+    private NextObjectiveTranslator nextTranslator;
+
+    private final ExecutorService callbackExecutor = SharedExecutors.getPoolThreadExecutor();
+
+    /**
+     * Creates a new instance of this behavior with the given capabilities.
+     *
+     * @param capabilities capabilities
+     */
+    public FabricPipeliner(FabricCapabilities capabilities) {
+        super(capabilities);
+    }
+
+    /**
+     * Create a new instance of this behaviour. Used by the abstract projectable
+     * model (i.e., {@link org.onosproject.net.Device#as(Class)}.
+     */
+    public FabricPipeliner() {
+        super();
+    }
+
+    @Override
+    public void init(DeviceId deviceId, PipelinerContext context) {
+        this.deviceId = deviceId;
+        this.flowRuleService = context.directory().get(FlowRuleService.class);
+        this.groupService = context.directory().get(GroupService.class);
+        this.flowObjectiveStore = context.directory().get(FlowObjectiveStore.class);
+        this.filteringTranslator = new FilteringObjectiveTranslator(deviceId, capabilities);
+        this.forwardingTranslator = new ForwardingObjectiveTranslator(deviceId, capabilities);
+        this.nextTranslator = new NextObjectiveTranslator(deviceId, capabilities);
+    }
+
+    @Override
+    public void filter(FilteringObjective obj) {
+        final ObjectiveTranslation result = filteringTranslator.translate(obj);
+        handleResult(obj, result);
+    }
+
+    @Override
+    public void forward(ForwardingObjective obj) {
+        final ObjectiveTranslation result = forwardingTranslator.translate(obj);
+        handleResult(obj, result);
+    }
+
+    @Override
+    public void next(NextObjective obj) {
+        if (obj.op() == Objective.Operation.VERIFY) {
+            // TODO: support VERIFY operation
+            log.debug("VERIFY operation not yet supported for NextObjective, will return success");
+            success(obj);
+            return;
+        }
+
+        if (obj.op() == Objective.Operation.MODIFY) {
+            // TODO: support MODIFY operation
+            log.warn("MODIFY operation not yet supported for NextObjective, will return failure :(");
+            fail(obj, ObjectiveError.UNSUPPORTED);
+            return;
+        }
+
+        final ObjectiveTranslation result = nextTranslator.translate(obj);
+        handleResult(obj, result);
+    }
+
+    @Override
+    public List<String> getNextMappings(NextGroup nextGroup) {
+        final FabricNextGroup fabricNextGroup = KRYO.deserialize(nextGroup.data());
+        return fabricNextGroup.nextMappings().stream()
+                .map(m -> format("%s -> %s", fabricNextGroup.type(), m))
+                .collect(Collectors.toList());
+    }
+
+    private void handleResult(Objective obj, ObjectiveTranslation result) {
+        if (result.error().isPresent()) {
+            fail(obj, result.error().get());
+            return;
+        }
+        processGroups(obj, result.groups());
+        processFlows(obj, result.flowRules());
+        if (obj instanceof NextObjective) {
+            handleNextGroup((NextObjective) obj);
+        }
+        success(obj);
+    }
+
+    private void handleNextGroup(NextObjective obj) {
+        switch (obj.op()) {
+            case REMOVE:
+                removeNextGroup(obj);
+                break;
+            case ADD:
+            case ADD_TO_EXISTING:
+            case REMOVE_FROM_EXISTING:
+            case MODIFY:
+                putNextGroup(obj);
+                break;
+            case VERIFY:
+                break;
+            default:
+                log.error("Unknown NextObjective operation '{}'", obj.op());
+        }
+    }
+
+    private void processFlows(Objective objective, Collection<FlowRule> flowRules) {
+        if (flowRules.isEmpty()) {
+            return;
+        }
+        final FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
+        switch (objective.op()) {
+            case ADD:
+            case ADD_TO_EXISTING:
+                flowRules.forEach(ops::add);
+                break;
+            case REMOVE:
+            case REMOVE_FROM_EXISTING:
+                flowRules.forEach(ops::remove);
+                break;
+            default:
+                log.warn("Unsupported Objective operation '{}'", objective.op());
+                return;
+        }
+        flowRuleService.apply(ops.build());
+    }
+
+    private void processGroups(Objective objective, Collection<GroupDescription> groups) {
+        if (groups.isEmpty()) {
+            return;
+        }
+        switch (objective.op()) {
+            case ADD:
+                groups.forEach(groupService::addGroup);
+                break;
+            case REMOVE:
+                groups.forEach(group -> groupService.removeGroup(
+                        deviceId, group.appCookie(), objective.appId()));
+                break;
+            case ADD_TO_EXISTING:
+                groups.forEach(group -> groupService.addBucketsToGroup(
+                        deviceId, group.appCookie(), group.buckets(),
+                        group.appCookie(), group.appId())
+                );
+                break;
+            case REMOVE_FROM_EXISTING:
+                groups.forEach(group -> groupService.removeBucketsFromGroup(
+                        deviceId, group.appCookie(), group.buckets(),
+                        group.appCookie(), group.appId())
+                );
+                break;
+            default:
+                log.warn("Unsupported Objective operation {}", objective.op());
+        }
+    }
+
+    private void fail(Objective objective, ObjectiveError error) {
+        CompletableFuture.runAsync(
+                () -> objective.context().ifPresent(
+                        ctx -> ctx.onError(objective, error)), callbackExecutor);
+
+    }
+
+
+    private void success(Objective objective) {
+        CompletableFuture.runAsync(
+                () -> objective.context().ifPresent(
+                        ctx -> ctx.onSuccess(objective)), callbackExecutor);
+    }
+
+    private void removeNextGroup(NextObjective obj) {
+        final NextGroup removed = flowObjectiveStore.removeNextGroup(obj.id());
+        if (removed == null) {
+            log.debug("NextGroup {} was not found in FlowObjectiveStore");
+        }
+    }
+
+    private void putNextGroup(NextObjective obj) {
+        final List<String> nextMappings = obj.nextTreatments().stream()
+                .map(this::nextTreatmentToMappingString)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+        final FabricNextGroup nextGroup = new FabricNextGroup(obj.type(), nextMappings);
+        flowObjectiveStore.putNextGroup(obj.id(), nextGroup);
+    }
+
+    private String nextTreatmentToMappingString(NextTreatment n) {
+        switch (n.type()) {
+            case TREATMENT:
+                final PortNumber p = outputPort(n);
+                return p == null ? "UNKNOWN"
+                        : format("OUTPUT:%s", p.toString());
+            case ID:
+                final IdNextTreatment id = (IdNextTreatment) n;
+                return format("NEXT_ID:%d", id.nextId());
+            default:
+                log.warn("Unknown NextTreatment type '{}'", n.type());
+                return "???";
+        }
+    }
+
+    /**
+     * NextGroup implementation.
+     */
+    private static class FabricNextGroup implements NextGroup {
+
+        private final NextObjective.Type type;
+        private final List<String> nextMappings;
+
+        FabricNextGroup(NextObjective.Type type, List<String> nextMappings) {
+            this.type = type;
+            this.nextMappings = ImmutableList.copyOf(nextMappings);
+        }
+
+        NextObjective.Type type() {
+            return type;
+        }
+
+        Collection<String> nextMappings() {
+            return nextMappings;
+        }
+
+        @Override
+        public byte[] data() {
+            return KRYO.serialize(this);
+        }
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipelinerException.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipelinerException.java
new file mode 100644
index 0000000..6755e75
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipelinerException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour.pipeliner;
+
+import org.onosproject.net.flowobjective.ObjectiveError;
+
+/**
+ * Signals an exception when translating a flow objective.
+ */
+class FabricPipelinerException extends Exception {
+
+    private final ObjectiveError error;
+
+    /**
+     * Creates a new exception for the given message. Sets ObjectiveError to
+     * UNSUPPORTED.
+     *
+     * @param message message
+     */
+    FabricPipelinerException(String message) {
+        super(message);
+        this.error = ObjectiveError.UNSUPPORTED;
+    }
+
+    /**
+     * Creates a new exception for the given message and ObjectiveError.
+     *
+     * @param message message
+     * @param error objective error
+     */
+    FabricPipelinerException(String message, ObjectiveError error) {
+        super(message);
+        this.error = error;
+    }
+
+    /**
+     * Returns the ObjectiveError of this exception.
+     *
+     * @return objective error
+     */
+    ObjectiveError objectiveError() {
+        return error;
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FilteringObjectiveTranslator.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FilteringObjectiveTranslator.java
new file mode 100644
index 0000000..d682d8c
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FilteringObjectiveTranslator.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour.pipeliner;
+
+import com.google.common.collect.Lists;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+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.EthCriterion;
+import org.onosproject.net.flow.criteria.PiCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.pi.runtime.PiAction;
+import org.onosproject.net.pi.runtime.PiActionParam;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricConstants;
+
+import java.util.Collection;
+import java.util.List;
+
+import static java.lang.String.format;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.criterion;
+
+/**
+ * ObjectiveTranslator implementation for FilteringObjective.
+ */
+class FilteringObjectiveTranslator
+        extends AbstractObjectiveTranslator<FilteringObjective> {
+
+    // Forwarding types from fabric.p4.
+    static final byte FWD_MPLS = 1;
+    static final byte FWD_IPV4_ROUTING = 2;
+    static final byte FWD_IPV6_ROUTING = 3;
+
+    private static final byte[] ONE = new byte[]{1};
+    private static final byte[] ZERO = new byte[]{0};
+
+    private static final PiAction DENY = PiAction.builder()
+            .withId(FabricConstants.FABRIC_INGRESS_FILTERING_DENY)
+            .build();
+
+
+    FilteringObjectiveTranslator(DeviceId deviceId, FabricCapabilities capabilities) {
+        super(deviceId, capabilities);
+    }
+
+    @Override
+    public ObjectiveTranslation doTranslate(FilteringObjective obj)
+            throws FabricPipelinerException {
+
+        final ObjectiveTranslation.Builder resultBuilder =
+                ObjectiveTranslation.builder();
+
+        if (obj.key() == null || obj.key().type() != Criterion.Type.IN_PORT) {
+            throw new FabricPipelinerException(
+                    format("Unsupported or missing filtering key: key=%s", obj.key()),
+                    ObjectiveError.BADPARAMS);
+        }
+
+        final PortCriterion inPort = (PortCriterion) obj.key();
+
+        final VlanIdCriterion outerVlan = (VlanIdCriterion) criterion(
+                obj.conditions(), Criterion.Type.VLAN_VID);
+        final VlanIdCriterion innerVlan = (VlanIdCriterion) criterion(
+                obj.conditions(), Criterion.Type.INNER_VLAN_VID);
+        final EthCriterion ethDst = (EthCriterion) criterion(
+                obj.conditions(), Criterion.Type.ETH_DST);
+        final EthCriterion ethDstMasked = (EthCriterion) criterion(
+                obj.conditions(), Criterion.Type.ETH_DST_MASKED);
+
+        ingressPortVlanRule(obj, inPort, outerVlan, innerVlan, resultBuilder);
+        fwdClassifierRules(obj, inPort, ethDst, ethDstMasked, resultBuilder);
+
+        return resultBuilder.build();
+    }
+
+    private void ingressPortVlanRule(
+            FilteringObjective obj,
+            Criterion inPortCriterion,
+            VlanIdCriterion outerVlanCriterion,
+            VlanIdCriterion innerVlanCriterion,
+            ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        final boolean outerVlanValid = outerVlanCriterion != null
+                && !outerVlanCriterion.vlanId().equals(VlanId.NONE);
+        final boolean innerVlanValid = innerVlanCriterion != null
+                && !innerVlanCriterion.vlanId().equals(VlanId.NONE);
+
+        final PiCriterion piCriterion = PiCriterion.builder()
+                .matchExact(FabricConstants.HDR_VLAN_IS_VALID, outerVlanValid ? ONE : ZERO)
+                .build();
+
+        final TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
+                .add(inPortCriterion)
+                .add(piCriterion);
+        if (outerVlanValid) {
+            selector.add(outerVlanCriterion);
+        }
+        if (innerVlanValid) {
+            selector.add(innerVlanCriterion);
+        }
+
+        final TrafficTreatment treatment;
+        if (obj.type().equals(FilteringObjective.Type.DENY)) {
+            treatment = DefaultTrafficTreatment.builder()
+                    .piTableAction(DENY)
+                    .build();
+        } else {
+            treatment = obj.meta() == null
+                    ? DefaultTrafficTreatment.emptyTreatment() : obj.meta();
+        }
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN,
+                selector.build(), treatment));
+    }
+
+    private void fwdClassifierRules(
+            FilteringObjective obj,
+            PortCriterion inPortCriterion,
+            EthCriterion ethDstCriterion,
+            EthCriterion ethDstMaskedCriterion,
+            ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        final List<FlowRule> flowRules = Lists.newArrayList();
+
+        final PortNumber inPort = inPortCriterion.port();
+        if (ethDstCriterion == null) {
+            if (ethDstMaskedCriterion == null) {
+                // No match. Do bridging (default action).
+                return;
+            }
+            // Masked fwd classifier rule
+            final MacAddress dstMac = ethDstMaskedCriterion.mac();
+            final MacAddress dstMacMask = ethDstMaskedCriterion.mask();
+            flowRules.add(maskedFwdClassifierRule(inPort, dstMac, dstMacMask, obj));
+        } else {
+            final MacAddress dstMac = ethDstCriterion.mac();
+            flowRules.addAll(ipFwdClassifierRules(inPort, dstMac, obj));
+            flowRules.add(mplsFwdClassifierRule(inPort, dstMac, obj));
+        }
+
+        for (FlowRule f : flowRules) {
+            resultBuilder.addFlowRule(f);
+        }
+    }
+
+    private FlowRule maskedFwdClassifierRule(
+            PortNumber inPort, MacAddress dstMac, MacAddress dstMacMask,
+            FilteringObjective obj)
+            throws FabricPipelinerException {
+        final TrafficTreatment treatment;
+        final short ethType;
+        if (dstMac.equals(MacAddress.IPV4_MULTICAST)
+                && dstMacMask.equals(MacAddress.IPV4_MULTICAST_MASK)) {
+            treatment = fwdClassifierTreatment(FWD_IPV4_ROUTING);
+            ethType = Ethernet.TYPE_IPV4;
+        } else if (dstMac.equals(MacAddress.IPV6_MULTICAST)
+                && dstMacMask.equals(MacAddress.IPV6_MULTICAST_MASK)) {
+            treatment = fwdClassifierTreatment(FWD_IPV6_ROUTING);
+            ethType = Ethernet.TYPE_IPV6;
+        } else {
+            throw new FabricPipelinerException(format(
+                    "Unsupported masked Ethernet address for fwd " +
+                            "classifier rule (mac=%s, mask=%s)",
+                    dstMac, dstMacMask));
+        }
+        return fwdClassifierRule(inPort, ethType, dstMac, dstMacMask, treatment, obj);
+    }
+
+    private Collection<FlowRule> ipFwdClassifierRules(
+            PortNumber inPort, MacAddress dstMac, FilteringObjective obj)
+            throws FabricPipelinerException {
+        final Collection<FlowRule> flowRules = Lists.newArrayList();
+        flowRules.add(fwdClassifierRule(
+                inPort, Ethernet.TYPE_IPV4, dstMac, null,
+                fwdClassifierTreatment(FWD_IPV4_ROUTING), obj));
+        flowRules.add(fwdClassifierRule(
+                inPort, Ethernet.TYPE_IPV6, dstMac, null,
+                fwdClassifierTreatment(FWD_IPV6_ROUTING), obj));
+        return flowRules;
+    }
+
+    private FlowRule mplsFwdClassifierRule(
+            PortNumber inPort, MacAddress dstMac, FilteringObjective obj)
+            throws FabricPipelinerException {
+        return fwdClassifierRule(
+                inPort, Ethernet.MPLS_UNICAST, dstMac, null,
+                fwdClassifierTreatment(FWD_MPLS), obj);
+    }
+
+    private FlowRule fwdClassifierRule(
+            PortNumber inPort, short ethType, MacAddress dstMac, MacAddress dstMacMask,
+            TrafficTreatment treatment, FilteringObjective obj)
+            throws FabricPipelinerException {
+        final TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(inPort)
+                .matchPi(mapEthTypeFwdClassifier(ethType))
+                .matchEthDstMasked(dstMac, dstMacMask == null
+                        ? MacAddress.EXACT_MASK : dstMacMask)
+                .build();
+        return flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER,
+                selector, treatment);
+    }
+
+    private TrafficTreatment fwdClassifierTreatment(byte fwdType) {
+        final PiActionParam param = new PiActionParam(FabricConstants.FWD_TYPE, fwdType);
+        final PiAction action = PiAction.builder()
+                .withId(FabricConstants.FABRIC_INGRESS_FILTERING_SET_FORWARDING_TYPE)
+                .withParameter(param)
+                .build();
+        return DefaultTrafficTreatment.builder()
+                .piTableAction(action)
+                .build();
+
+    }
+
+    static PiCriterion mapEthTypeFwdClassifier(short ethType) {
+        // Map the Ethernet type to the validity bits of the fabric pipeline
+        switch (EthType.EtherType.lookup(ethType)) {
+            case IPV4: {
+                return PiCriterion.builder()
+                        .matchExact(FabricConstants.HDR_IS_IPV4, ONE)
+                        .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
+                        .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
+                        .build();
+            }
+            case IPV6: {
+                return PiCriterion.builder()
+                        .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
+                        .matchExact(FabricConstants.HDR_IS_IPV6, ONE)
+                        .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
+                        .build();
+            }
+            case MPLS_UNICAST: {
+                return PiCriterion.builder()
+                        .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
+                        .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
+                        .matchExact(FabricConstants.HDR_IS_MPLS, ONE)
+                        .build();
+            }
+            default: {
+                return PiCriterion.builder()
+                        .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
+                        .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
+                        .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
+                        .build();
+            }
+        }
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingFunctionType.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingFunctionType.java
new file mode 100644
index 0000000..1e33fa5
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingFunctionType.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour.pipeliner;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.slf4j.Logger;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.onosproject.net.flow.criteria.Criterion.Type.ETH_DST;
+import static org.onosproject.net.flow.criteria.Criterion.Type.ETH_TYPE;
+import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST;
+import static org.onosproject.net.flow.criteria.Criterion.Type.IPV6_DST;
+import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_BOS;
+import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_LABEL;
+import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_ETH_DST_NONE;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_ETH_TYPE_IPV4;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_ETH_TYPE_IPV6;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_ETH_TYPE_MPLS;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_MPLS_BOS_FALSE;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_MPLS_BOS_TRUE;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Forwarding function types (FFTs) that can represent a given forwarding
+ * objective. Each FFT is defined by a subset of criterion types expected to be
+ * found in the selector of the given objective, and, optionally, by their
+ * respective values (criterion instances) to match or to mismatch.
+ */
+enum ForwardingFunctionType {
+    /**
+     * L2 unicast.
+     */
+    L2_UNICAST(
+            Sets.newHashSet(VLAN_VID, ETH_DST), // Expected criterion types.
+            Collections.emptyList(), // Criteria to match.
+            Lists.newArrayList(MATCH_ETH_DST_NONE)), // Criteria NOT to match.
+
+    /**
+     * L2 broadcast.
+     */
+    L2_BROADCAST(
+            Sets.newHashSet(VLAN_VID, ETH_DST),
+            Lists.newArrayList(MATCH_ETH_DST_NONE),
+            Collections.emptyList()),
+    L2_BROADCAST_ALIAS(
+            Sets.newHashSet(VLAN_VID),
+            Collections.emptyList(),
+            Collections.emptyList(),
+            L2_BROADCAST), // (Optional) FFT to return if selected.
+
+    /**
+     * IPv4 unicast.
+     */
+    IPV4_ROUTING(
+            Sets.newHashSet(ETH_TYPE, IPV4_DST),
+            Lists.newArrayList(MATCH_ETH_TYPE_IPV4),
+            Collections.emptyList()),
+
+    /**
+     * IPv4 multicast.
+     */
+    IPV4_ROUTING_MULTICAST(
+            Sets.newHashSet(ETH_TYPE, VLAN_VID, IPV4_DST),
+            Lists.newArrayList(MATCH_ETH_TYPE_IPV4),
+            Collections.emptyList()),
+
+    /**
+     * IPv6 unicast.
+     */
+    IPV6_ROUTING(
+            Sets.newHashSet(ETH_TYPE, IPV6_DST),
+            Lists.newArrayList(MATCH_ETH_TYPE_IPV6),
+            Collections.emptyList()),
+
+    /**
+     * IPv6 multicast.
+     */
+    IPV6_ROUTING_MULTICAST(
+            Sets.newHashSet(ETH_TYPE, VLAN_VID, IPV6_DST),
+            Lists.newArrayList(MATCH_ETH_TYPE_IPV6),
+            Collections.emptyList()),
+
+    /**
+     * MPLS segment routing.
+     */
+    MPLS_SEGMENT_ROUTING(
+            Sets.newHashSet(ETH_TYPE, MPLS_LABEL, MPLS_BOS),
+            Lists.newArrayList(MATCH_ETH_TYPE_MPLS, MATCH_MPLS_BOS_TRUE),
+            Collections.emptyList()),
+
+    /**
+     * Pseudo-wire.
+     */
+    PSEUDO_WIRE(
+            Sets.newHashSet(ETH_TYPE, MPLS_LABEL, MPLS_BOS),
+            Lists.newArrayList(MATCH_ETH_TYPE_MPLS, MATCH_MPLS_BOS_FALSE),
+            Collections.emptyList()),
+
+    /**
+     * Unsupported type.
+     */
+    UNKNOWN(
+            Collections.emptySet(),
+            Collections.emptyList(),
+            Collections.emptyList());
+
+    private static final Logger log = getLogger(ForwardingFunctionType.class);
+
+    private final Set<Criterion.Type> expectedCriterionTypes;
+    private final Map<Criterion.Type, List<Criterion>> matchCriteria;
+    private final Map<Criterion.Type, List<Criterion>> mismatchCriteria;
+    private final ForwardingFunctionType originalType;
+
+    /**
+     * Creates a new FFT.
+     *
+     * @param expectedCriterionTypes expected criterion types
+     * @param matchCriteria          criterion instances to match
+     * @param mismatchCriteria       criterion instance not to be matched
+     */
+    ForwardingFunctionType(Set<Criterion.Type> expectedCriterionTypes,
+                           Collection<Criterion> matchCriteria,
+                           Collection<Criterion> mismatchCriteria) {
+        this(expectedCriterionTypes, matchCriteria, mismatchCriteria, null);
+    }
+
+    /**
+     * Creates a new alias FFT that if matched, should return the given original
+     * FFT.
+     *
+     * @param expectedCriterionTypes expected criterion types
+     * @param matchCriteria          criterion instances to match
+     * @param mismatchCriteria       criterion instance not to be matched
+     * @param original               original FFT to return
+     */
+    ForwardingFunctionType(Set<Criterion.Type> expectedCriterionTypes,
+                           Collection<Criterion> matchCriteria,
+                           Collection<Criterion> mismatchCriteria,
+                           ForwardingFunctionType original) {
+        this.expectedCriterionTypes = ImmutableSet.copyOf(expectedCriterionTypes);
+        this.matchCriteria = typeToCriteriaMap(matchCriteria);
+        this.mismatchCriteria = typeToCriteriaMap(mismatchCriteria);
+        this.originalType = original == null ? this : original;
+    }
+
+    /**
+     * Attempts to guess the forwarding function type of the given forwarding
+     * objective.
+     *
+     * @param fwd the forwarding objective
+     * @return forwarding function type. {@link #UNKNOWN} if the FFT cannot be
+     * determined.
+     */
+    public static ForwardingFunctionType getForwardingFunctionType(ForwardingObjective fwd) {
+        final Set<Criterion> criteria = criteriaIncludingMeta(fwd);
+        final Set<Criterion.Type> criterionTypes = criteria.stream()
+                .map(Criterion::type).collect(Collectors.toSet());
+
+        final List<ForwardingFunctionType> candidates = Arrays.stream(ForwardingFunctionType.values())
+                // Keep FFTs which expected criterion types are the same found
+                // in the fwd objective.
+                .filter(fft -> fft.expectedCriterionTypes.equals(criterionTypes))
+                // Keep FFTs which match criteria are found in the fwd objective.
+                .filter(fft -> matchFft(criteria, fft))
+                // Keep FFTs which mismatch criteria are NOT found in the objective.
+                .filter(fft -> mismatchFft(criteria, fft))
+                .collect(Collectors.toList());
+
+        switch (candidates.size()) {
+            case 1:
+                return candidates.get(0).originalType;
+            case 0:
+                return UNKNOWN;
+            default:
+                log.warn("Multiple FFT candidates found: {} [{}]", candidates, fwd);
+                return UNKNOWN;
+        }
+    }
+
+    private static boolean matchFft(Collection<Criterion> criteria, ForwardingFunctionType fft) {
+        return matchOrMismatchFft(criteria, fft.matchCriteria, false);
+    }
+
+    private static boolean mismatchFft(Collection<Criterion> criteria, ForwardingFunctionType fft) {
+        return matchOrMismatchFft(criteria, fft.mismatchCriteria, true);
+    }
+
+    private static boolean matchOrMismatchFft(
+            Collection<Criterion> criteria,
+            Map<Criterion.Type, List<Criterion>> criteriaToMatch,
+            boolean mismatch) {
+        final Map<Criterion.Type, Criterion> givenCriteria = typeToCriterionMap(criteria);
+        for (Criterion.Type typeToMatch : criteriaToMatch.keySet()) {
+            if (!givenCriteria.containsKey(typeToMatch)) {
+                return false;
+            }
+            final boolean matchFound = criteriaToMatch.get(typeToMatch).stream()
+                    .anyMatch(c -> mismatch != givenCriteria.get(c.type()).equals(c));
+            if (!matchFound) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static Set<Criterion> criteriaIncludingMeta(ForwardingObjective fwd) {
+        final Set<Criterion> criteria = Sets.newHashSet();
+        criteria.addAll(fwd.selector().criteria());
+        // FIXME: Is this really needed? Meta is such an ambiguous field...
+        if (fwd.meta() != null) {
+            criteria.addAll(fwd.meta().criteria());
+        }
+        return criteria;
+    }
+
+    private static Map<Criterion.Type, List<Criterion>> typeToCriteriaMap(Collection<Criterion> criteria) {
+        return criteria.stream().collect(Collectors.groupingBy(Criterion::type));
+    }
+
+    private static Map<Criterion.Type, Criterion> typeToCriterionMap(Collection<Criterion> criteria) {
+        final ImmutableMap.Builder<Criterion.Type, Criterion> mapBuilder = ImmutableMap.builder();
+        criteria.forEach(c -> mapBuilder.put(c.type(), c));
+        return mapBuilder.build();
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingObjectiveTranslator.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingObjectiveTranslator.java
new file mode 100644
index 0000000..1d7d5c0
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingObjectiveTranslator.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour.pipeliner;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+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.EthCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.pi.model.PiActionId;
+import org.onosproject.net.pi.model.PiTableId;
+import org.onosproject.net.pi.runtime.PiAction;
+import org.onosproject.net.pi.runtime.PiActionParam;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricConstants;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+import static org.onosproject.net.group.DefaultGroupBucket.createCloneGroupBucket;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.criterionNotNull;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.outputPort;
+
+
+/**
+ * ObjectiveTranslator implementation ForwardingObjective.
+ */
+class ForwardingObjectiveTranslator
+        extends AbstractObjectiveTranslator<ForwardingObjective> {
+
+    //FIXME: Max number supported by PI
+    static final int CLONE_TO_CPU_ID = 511;
+    private static final List<String> DEFAULT_ROUTE_PREFIXES = Lists.newArrayList(
+            "0.0.0.0/1", "128.0.0.0/1");
+
+    private static final Set<Criterion.Type> ACL_CRITERIA = ImmutableSet.of(
+            Criterion.Type.IN_PORT,
+            Criterion.Type.IN_PHY_PORT,
+            Criterion.Type.ETH_DST,
+            Criterion.Type.ETH_DST_MASKED,
+            Criterion.Type.ETH_SRC,
+            Criterion.Type.ETH_SRC_MASKED,
+            Criterion.Type.ETH_TYPE,
+            Criterion.Type.VLAN_VID,
+            Criterion.Type.IP_PROTO,
+            Criterion.Type.IPV4_SRC,
+            Criterion.Type.IPV4_DST,
+            Criterion.Type.TCP_SRC,
+            Criterion.Type.TCP_SRC_MASKED,
+            Criterion.Type.TCP_DST,
+            Criterion.Type.TCP_DST_MASKED,
+            Criterion.Type.UDP_SRC,
+            Criterion.Type.UDP_SRC_MASKED,
+            Criterion.Type.UDP_DST,
+            Criterion.Type.UDP_DST_MASKED,
+            Criterion.Type.ICMPV4_TYPE,
+            Criterion.Type.ICMPV4_CODE,
+            Criterion.Type.PROTOCOL_INDEPENDENT);
+
+    private static final Map<PiTableId, PiActionId> NEXT_ID_ACTIONS = ImmutableMap.<PiTableId, PiActionId>builder()
+            .put(FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING,
+                 FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_BRIDGING)
+            .put(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
+                 FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V4)
+            .put(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V6,
+                 FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V6)
+            .put(FabricConstants.FABRIC_INGRESS_FORWARDING_MPLS,
+                 FabricConstants.FABRIC_INGRESS_FORWARDING_POP_MPLS_AND_NEXT)
+            .build();
+
+    ForwardingObjectiveTranslator(DeviceId deviceId, FabricCapabilities capabilities) {
+        super(deviceId, capabilities);
+    }
+
+    @Override
+    public ObjectiveTranslation doTranslate(ForwardingObjective obj)
+            throws FabricPipelinerException {
+        final ObjectiveTranslation.Builder resultBuilder =
+                ObjectiveTranslation.builder();
+        switch (obj.flag()) {
+            case SPECIFIC:
+                processSpecificFwd(obj, resultBuilder);
+                break;
+            case VERSATILE:
+                processVersatileFwd(obj, resultBuilder);
+                break;
+            case EGRESS:
+            default:
+                log.warn("Unsupported ForwardingObjective type '{}'", obj.flag());
+                return ObjectiveTranslation.ofError(ObjectiveError.UNSUPPORTED);
+        }
+        return resultBuilder.build();
+    }
+
+    private void processVersatileFwd(ForwardingObjective obj,
+                                     ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        final Set<Criterion.Type> unsupportedCriteria = obj.selector().criteria()
+                .stream()
+                .map(Criterion::type)
+                .filter(t -> !ACL_CRITERIA.contains(t))
+                .collect(Collectors.toSet());
+
+        if (!unsupportedCriteria.isEmpty()) {
+            throw new FabricPipelinerException(format(
+                    "unsupported ACL criteria %s", unsupportedCriteria.toString()));
+        }
+
+        aclRule(obj, resultBuilder);
+    }
+
+    private void processSpecificFwd(ForwardingObjective obj,
+                                    ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        final Set<Criterion> criteriaWithMeta = Sets.newHashSet(obj.selector().criteria());
+
+        // FIXME: Is this really needed? Meta is such an ambiguous field...
+        // Why would we match on a META field?
+        if (obj.meta() != null) {
+            criteriaWithMeta.addAll(obj.meta().criteria());
+        }
+
+        final ForwardingFunctionType fft = ForwardingFunctionType.getForwardingFunctionType(obj);
+
+        switch (fft) {
+            case UNKNOWN:
+                throw new FabricPipelinerException(
+                        "unable to detect forwarding function type");
+            case L2_UNICAST:
+                bridgingRule(obj, criteriaWithMeta, resultBuilder, false);
+                break;
+            case L2_BROADCAST:
+                bridgingRule(obj, criteriaWithMeta, resultBuilder, true);
+                break;
+            case IPV4_ROUTING:
+            case IPV4_ROUTING_MULTICAST:
+                ipv4RoutingRule(obj, criteriaWithMeta, resultBuilder);
+                break;
+            case MPLS_SEGMENT_ROUTING:
+                mplsRule(obj, criteriaWithMeta, resultBuilder);
+                break;
+            case IPV6_ROUTING:
+            case IPV6_ROUTING_MULTICAST:
+            default:
+                throw new FabricPipelinerException(format(
+                        "unsupported forwarding function type '%s'",
+                        fft));
+        }
+    }
+
+    private void bridgingRule(ForwardingObjective obj, Set<Criterion> criteriaWithMeta,
+                              ObjectiveTranslation.Builder resultBuilder,
+                              boolean broadcast)
+            throws FabricPipelinerException {
+
+        final VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) criterionNotNull(
+                criteriaWithMeta, Criterion.Type.VLAN_VID);
+        final TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
+                .add(vlanIdCriterion);
+
+        if (!broadcast) {
+            final EthCriterion ethDstCriterion = (EthCriterion) criterionNotNull(
+                    obj.selector(), Criterion.Type.ETH_DST);
+            selector.matchEthDstMasked(ethDstCriterion.mac(), MacAddress.EXACT_MASK);
+        }
+
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING, selector.build()));
+    }
+
+    private void ipv4RoutingRule(ForwardingObjective obj, Set<Criterion> criteriaWithMeta,
+                                 ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+        final IPCriterion ipDstCriterion = (IPCriterion) criterionNotNull(
+                criteriaWithMeta, Criterion.Type.IPV4_DST);
+
+        if (ipDstCriterion.ip().prefixLength() == 0) {
+            defaultIpv4Route(obj, resultBuilder);
+            return;
+        }
+
+        final TrafficSelector selector = DefaultTrafficSelector.builder()
+                .add(ipDstCriterion)
+                .build();
+
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4, selector));
+    }
+
+    private void defaultIpv4Route(ForwardingObjective obj,
+                                  ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        // Hack to work around the inability to program default rules.
+        for (String prefix : DEFAULT_ROUTE_PREFIXES) {
+            final TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf(prefix)).build();
+            resultBuilder.addFlowRule(flowRule(
+                    obj, FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4, selector));
+        }
+    }
+
+    private void mplsRule(ForwardingObjective obj, Set<Criterion> criteriaWithMeta,
+                          ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        final MplsCriterion mplsCriterion = (MplsCriterion) criterionNotNull(
+                criteriaWithMeta, Criterion.Type.MPLS_LABEL);
+        final TrafficSelector selector = DefaultTrafficSelector.builder()
+                .add(mplsCriterion)
+                .build();
+
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_FORWARDING_MPLS, selector));
+    }
+
+    private void aclRule(ForwardingObjective obj,
+                         ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+        if (obj.nextId() == null && obj.treatment() != null) {
+            final TrafficTreatment treatment = obj.treatment();
+            final PortNumber outPort = outputPort(treatment);
+            if (outPort != null
+                    && outPort.equals(PortNumber.CONTROLLER)
+                    && treatment.allInstructions().size() == 1) {
+
+                final PiAction aclAction;
+                if (treatment.clearedDeferred()) {
+                    aclAction = PiAction.builder()
+                            .withId(FabricConstants.FABRIC_INGRESS_ACL_PUNT_TO_CPU)
+                            .build();
+                } else {
+                    // Action is SET_CLONE_SESSION_ID
+                    if (obj.op() == Objective.Operation.ADD) {
+                        // Action is ADD, create clone group
+                        final DefaultGroupDescription cloneGroup =
+                                createCloneGroup(obj.appId(),
+                                                 CLONE_TO_CPU_ID,
+                                                 outPort);
+                        resultBuilder.addGroup(cloneGroup);
+                    }
+                    aclAction = PiAction.builder()
+                            .withId(FabricConstants.FABRIC_INGRESS_ACL_SET_CLONE_SESSION_ID)
+                            .withParameter(new PiActionParam(
+                                    FabricConstants.CLONE_ID, CLONE_TO_CPU_ID))
+                            .build();
+                }
+                final TrafficTreatment piTreatment = DefaultTrafficTreatment.builder()
+                        .piTableAction(aclAction)
+                        .build();
+                resultBuilder.addFlowRule(flowRule(
+                        obj, FabricConstants.FABRIC_INGRESS_ACL_ACL, obj.selector(), piTreatment));
+                return;
+            }
+        }
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_ACL_ACL, obj.selector()));
+    }
+
+    private DefaultGroupDescription createCloneGroup(
+            ApplicationId appId,
+            int cloneSessionId,
+            PortNumber outPort) {
+        final GroupKey groupKey = new DefaultGroupKey(
+                FabricPipeliner.KRYO.serialize(cloneSessionId));
+
+        final List<GroupBucket> bucketList = ImmutableList.of(
+                createCloneGroupBucket(DefaultTrafficTreatment.builder()
+                                               .setOutput(outPort)
+                                               .build()));
+        final DefaultGroupDescription cloneGroup = new DefaultGroupDescription(
+                deviceId, GroupDescription.Type.CLONE,
+                new GroupBuckets(bucketList),
+                groupKey, cloneSessionId, appId);
+        return cloneGroup;
+    }
+
+    private FlowRule flowRule(
+            ForwardingObjective obj, PiTableId tableId, TrafficSelector selector)
+            throws FabricPipelinerException {
+        return flowRule(obj, tableId, selector, nextIdOrTreatment(obj, tableId));
+    }
+
+    private static TrafficTreatment nextIdOrTreatment(
+            ForwardingObjective obj, PiTableId tableId)
+            throws FabricPipelinerException {
+        if (obj.nextId() == null) {
+            return obj.treatment();
+        } else {
+            if (!NEXT_ID_ACTIONS.containsKey(tableId)) {
+                throw new FabricPipelinerException(format(
+                        "BUG? no next_id action set for table %s", tableId));
+            }
+            return DefaultTrafficTreatment.builder()
+                    .piTableAction(
+                            setNextIdAction(obj.nextId(),
+                                            NEXT_ID_ACTIONS.get(tableId)))
+                    .build();
+        }
+    }
+
+    private static PiAction setNextIdAction(Integer nextId, PiActionId actionId) {
+        final PiActionParam nextIdParam = new PiActionParam(FabricConstants.NEXT_ID, nextId);
+        return PiAction.builder()
+                .withId(actionId)
+                .withParameter(nextIdParam)
+                .build();
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java
new file mode 100644
index 0000000..4e3304d
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java
@@ -0,0 +1,506 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour.pipeliner;
+
+import com.google.common.collect.Lists;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+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.PiCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
+import org.onosproject.net.flowobjective.DefaultNextTreatment;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.NextTreatment;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.pi.model.PiTableId;
+import org.onosproject.net.pi.runtime.PiAction;
+import org.onosproject.net.pi.runtime.PiActionParam;
+import org.onosproject.net.pi.runtime.PiActionProfileGroupId;
+import org.onosproject.net.pi.runtime.PiGroupKey;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricConstants;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_ID;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_POP;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.criterion;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.l2Instruction;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.l2Instructions;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.outputPort;
+
+/**
+ * ObjectiveTranslator implementation for NextObjective.
+ */
+class NextObjectiveTranslator
+        extends AbstractObjectiveTranslator<NextObjective> {
+
+    private static final String XCONNECT = "xconnect";
+
+    NextObjectiveTranslator(DeviceId deviceId, FabricCapabilities capabilities) {
+        super(deviceId, capabilities);
+    }
+
+    @Override
+    public ObjectiveTranslation doTranslate(NextObjective obj)
+            throws FabricPipelinerException {
+
+        final ObjectiveTranslation.Builder resultBuilder =
+                ObjectiveTranslation.builder();
+
+        switch (obj.type()) {
+            case SIMPLE:
+                simpleNext(obj, resultBuilder, false);
+                break;
+            case HASHED:
+                hashedNext(obj, resultBuilder);
+                break;
+            case BROADCAST:
+                if (isXconnect(obj)) {
+                    xconnectNext(obj, resultBuilder);
+                } else {
+                    multicastNext(obj, resultBuilder);
+                }
+                break;
+            default:
+                log.warn("Unsupported NextObjective type '{}'", obj);
+                return ObjectiveTranslation.ofError(ObjectiveError.UNSUPPORTED);
+        }
+
+        if (!isGroupModifyOp(obj)) {
+            // Generate next VLAN rules.
+            nextVlan(obj, resultBuilder);
+        }
+
+        return resultBuilder.build();
+    }
+
+    private void nextVlan(NextObjective obj,
+                          ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+        // We expect NextObjective treatments to contain one or two VLAN instructions.
+        // If two, this treatment should be mapped to an action for double-vlan push.
+        // In fabric.p4, mapping next IDs to VLAN IDs is done by a direct table (next_vlan),
+        // for this reason, we also make sure that all treatments in the NextObjective
+        // have exactly the same VLAN instructions, as they will be mapped to a single action
+
+        // Try to extract VLAN instructions in the treatment,
+        //  later we check if we support multiple VLAN termination.
+        final List<List<ModVlanIdInstruction>> vlanInstructions = defaultNextTreatments(
+                obj.nextTreatments(), false).stream()
+                .map(defaultNextTreatment ->
+                             l2Instructions(defaultNextTreatment.treatment(), VLAN_ID)
+                                     .stream().map(v -> (ModVlanIdInstruction) v)
+                                     .collect(Collectors.toList()))
+                .filter(l -> !l.isEmpty())
+                .collect(Collectors.toList());
+
+        final VlanIdCriterion vlanIdCriterion = obj.meta() == null ? null
+                : (VlanIdCriterion) criterion(obj.meta().criteria(), Criterion.Type.VLAN_VID);
+
+        final List<VlanId> vlanIdList;
+        if (vlanInstructions.isEmpty() && vlanIdCriterion == null) {
+            // No VLAN_ID to apply.
+            return;
+        }
+        if (!vlanInstructions.isEmpty()) {
+            // Give priority to what found in the instructions.
+            // Expect the same VLAN ID (or two VLAN IDs in the same order) for all instructions.
+            final Set<List<VlanId>> vlanIds = vlanInstructions.stream()
+                    .map(l -> l.stream().map(ModVlanIdInstruction::vlanId).collect(Collectors.toList()))
+                    .collect(Collectors.toSet());
+            if (obj.nextTreatments().size() != vlanInstructions.size() ||
+                    vlanIds.size() != 1) {
+                throw new FabricPipelinerException(
+                        "Inconsistent VLAN_ID instructions, cannot process " +
+                                "next_vlan rule. It is required that all " +
+                                "treatments have the same VLAN_ID instructions.");
+            }
+            vlanIdList = vlanIds.iterator().next();
+        } else {
+            // Use the value in meta.
+            // FIXME: there should be no need to generate a next_vlan rule for
+            //  the value found in meta. Meta describes the fields that were
+            //  expected to be matched in previous pipeline stages, i.e.
+            //  existing packet fields. But, for some reason, if we remove this
+            //  rule, traffic is not forwarded at spines. We might need to look
+            //  at the way default VLANs are handled in fabric.p4.
+            vlanIdList = List.of(vlanIdCriterion.vlanId());
+        }
+
+        final TrafficSelector selector = nextIdSelector(obj.id());
+        final TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+        vlanIdList.stream().forEach(vlanId -> treatmentBuilder.setVlanId(vlanId));
+        final TrafficTreatment treatment = treatmentBuilder.build();
+
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_NEXT_NEXT_VLAN,
+                selector, treatment));
+    }
+
+    private void simpleNext(NextObjective obj,
+                            ObjectiveTranslation.Builder resultBuilder,
+                            boolean forceSimple)
+            throws FabricPipelinerException {
+
+        if (capabilities.hasHashedTable()) {
+            // Use hashed table when possible.
+            hashedNext(obj, resultBuilder);
+            return;
+        }
+
+        if (obj.nextTreatments().isEmpty()) {
+            // Do nothing.
+            return;
+        } else if (!forceSimple && obj.nextTreatments().size() != 1) {
+            throw new FabricPipelinerException(format(
+                    "SIMPLE NextObjective should contain only 1 treatment, found %d",
+                    obj.nextTreatments().size()), ObjectiveError.BADPARAMS);
+        }
+
+        final TrafficSelector selector = nextIdSelector(obj.id());
+
+        final List<DefaultNextTreatment> treatments = defaultNextTreatments(
+                obj.nextTreatments(), true);
+
+        if (forceSimple && treatments.size() > 1) {
+            log.warn("Forcing SIMPLE behavior for NextObjective with {} treatments []",
+                     treatments.size(), obj);
+        }
+
+        // If not forcing, we are essentially extracting the only available treatment.
+        final TrafficTreatment treatment = defaultNextTreatments(
+                obj.nextTreatments(), true).get(0).treatment();
+
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_NEXT_SIMPLE,
+                selector, treatment));
+
+        handleEgress(obj, treatment, resultBuilder, false);
+    }
+
+    private void hashedNext(NextObjective obj,
+                            ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        if (!capabilities.hasHashedTable()) {
+            simpleNext(obj, resultBuilder, true);
+            return;
+        }
+
+        // Updated result builder with hashed group.
+        final int groupId = selectGroup(obj, resultBuilder);
+
+        if (isGroupModifyOp(obj)) {
+            // No changes to flow rules.
+            return;
+        }
+
+        final TrafficSelector selector = nextIdSelector(obj.id());
+        final TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .piTableAction(PiActionProfileGroupId.of(groupId))
+                .build();
+
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_NEXT_HASHED,
+                selector, treatment));
+    }
+
+    private void handleEgress(NextObjective obj, TrafficTreatment treatment,
+                              ObjectiveTranslation.Builder resultBuilder,
+                              boolean strict)
+            throws FabricPipelinerException {
+        final PortNumber outPort = outputPort(treatment);
+        final Instruction popVlanInst = l2Instruction(treatment, VLAN_POP);
+        if (popVlanInst != null && outPort != null) {
+            if (strict && treatment.allInstructions().size() > 2) {
+                throw new FabricPipelinerException(
+                        "Treatment contains instructions other " +
+                                "than OUTPUT and VLAN_POP, cannot generate " +
+                                "egress rules");
+            }
+            egressVlanPop(outPort, obj, resultBuilder);
+        }
+    }
+
+    private void egressVlanPop(PortNumber outPort, NextObjective obj,
+                               ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        if (obj.meta() == null) {
+            throw new FabricPipelinerException(
+                    "Cannot process egress pop VLAN rule, NextObjective has null meta",
+                    ObjectiveError.BADPARAMS);
+        }
+
+        final VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) criterion(
+                obj.meta(), Criterion.Type.VLAN_VID);
+        if (vlanIdCriterion == null) {
+            throw new FabricPipelinerException(
+                    "Cannot process egress pop VLAN rule, missing VLAN_VID criterion " +
+                            "in NextObjective meta",
+                    ObjectiveError.BADPARAMS);
+        }
+
+        final PiCriterion egressVlanTableMatch = PiCriterion.builder()
+                .matchExact(FabricConstants.HDR_EG_PORT, outPort.toLong())
+                .build();
+        final TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchPi(egressVlanTableMatch)
+                .matchVlanId(vlanIdCriterion.vlanId())
+                .build();
+        final TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .popVlan()
+                .build();
+
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_EGRESS_EGRESS_NEXT_EGRESS_VLAN,
+                selector, treatment));
+    }
+
+    private TrafficSelector nextIdSelector(int nextId) {
+        return nextIdSelectorBuilder(nextId).build();
+    }
+
+    private TrafficSelector.Builder nextIdSelectorBuilder(int nextId) {
+        final PiCriterion nextIdCriterion = PiCriterion.builder()
+                .matchExact(FabricConstants.HDR_NEXT_ID, nextId)
+                .build();
+        return DefaultTrafficSelector.builder()
+                .matchPi(nextIdCriterion);
+    }
+
+    private void xconnectNext(NextObjective obj, ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        final Collection<DefaultNextTreatment> defaultNextTreatments =
+                defaultNextTreatments(obj.nextTreatments(), true);
+
+        final List<PortNumber> outPorts = defaultNextTreatments.stream()
+                .map(DefaultNextTreatment::treatment)
+                .map(FabricUtils::outputPort)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+
+        if (outPorts.size() != 2) {
+            throw new FabricPipelinerException(format(
+                    "Handling XCONNECT with %d treatments (ports), but expected is 2",
+                    defaultNextTreatments.size()), ObjectiveError.UNSUPPORTED);
+        }
+
+        final PortNumber port1 = outPorts.get(0);
+        final PortNumber port2 = outPorts.get(1);
+        final TrafficSelector selector1 = nextIdSelectorBuilder(obj.id())
+                .matchInPort(port1)
+                .build();
+        final TrafficTreatment treatment1 = DefaultTrafficTreatment.builder()
+                .setOutput(port2)
+                .build();
+        final TrafficSelector selector2 = nextIdSelectorBuilder(obj.id())
+                .matchInPort(port2)
+                .build();
+        final TrafficTreatment treatment2 = DefaultTrafficTreatment.builder()
+                .setOutput(port1)
+                .build();
+
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_NEXT_XCONNECT,
+                selector1, treatment1));
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_NEXT_XCONNECT,
+                selector2, treatment2));
+
+    }
+
+    private void multicastNext(NextObjective obj,
+                               ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        // Create ALL group that will be translated to a PRE multicast entry.
+        final int groupId = allGroup(obj, resultBuilder);
+
+        if (isGroupModifyOp(obj)) {
+            // No changes to flow rules.
+            return;
+        }
+
+        final TrafficSelector selector = nextIdSelector(obj.id());
+        final PiActionParam groupIdParam = new PiActionParam(
+                FabricConstants.GROUP_ID, groupId);
+        final PiAction setMcGroupAction = PiAction.builder()
+                .withId(FabricConstants.FABRIC_INGRESS_NEXT_SET_MCAST_GROUP_ID)
+                .withParameter(groupIdParam)
+                .build();
+        final TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .piTableAction(setMcGroupAction)
+                .build();
+
+        resultBuilder.addFlowRule(flowRule(
+                obj, FabricConstants.FABRIC_INGRESS_NEXT_MULTICAST,
+                selector, treatment));
+    }
+
+    private int selectGroup(NextObjective obj,
+                            ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        final PiTableId hashedTableId = FabricConstants.FABRIC_INGRESS_NEXT_HASHED;
+        final List<DefaultNextTreatment> defaultNextTreatments =
+                defaultNextTreatments(obj.nextTreatments(), true);
+        final List<TrafficTreatment> piTreatments = Lists.newArrayList();
+
+        for (DefaultNextTreatment t : defaultNextTreatments) {
+            // Map treatment to PI...
+            piTreatments.add(mapTreatmentToPiIfNeeded(t.treatment(), hashedTableId));
+            // ...and handle egress if necessary.
+            handleEgress(obj, t.treatment(), resultBuilder, false);
+        }
+
+        final List<GroupBucket> bucketList = piTreatments.stream()
+                .map(DefaultGroupBucket::createSelectGroupBucket)
+                .collect(Collectors.toList());
+
+        final int groupId = obj.id();
+        final PiGroupKey groupKey = new PiGroupKey(
+                hashedTableId,
+                FabricConstants.FABRIC_INGRESS_NEXT_HASHED_SELECTOR,
+                groupId);
+
+        resultBuilder.addGroup(new DefaultGroupDescription(
+                deviceId,
+                GroupDescription.Type.SELECT,
+                new GroupBuckets(bucketList),
+                groupKey,
+                groupId,
+                obj.appId()));
+
+        return groupId;
+    }
+
+    private int allGroup(NextObjective obj,
+                         ObjectiveTranslation.Builder resultBuilder)
+            throws FabricPipelinerException {
+
+        final Collection<DefaultNextTreatment> defaultNextTreatments =
+                defaultNextTreatments(obj.nextTreatments(), true);
+        // No need to map treatments to PI as translation of ALL groups to PRE
+        // multicast entries is based solely on the output port.
+        for (DefaultNextTreatment t : defaultNextTreatments) {
+            handleEgress(obj, t.treatment(), resultBuilder, true);
+        }
+
+        // FIXME: this implementation supports only the case in which each
+        // switch interface is associated with only one VLAN, otherwise we would
+        // need to support replicating multiple times the same packet for the
+        // same port while setting different VLAN IDs. Hence, collect in a set.
+        final Set<PortNumber> outPorts = defaultNextTreatments.stream()
+                .map(DefaultNextTreatment::treatment)
+                .map(FabricUtils::outputPort)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+        if (outPorts.size() != defaultNextTreatments.size()) {
+            throw new FabricPipelinerException(format(
+                    "Found BROADCAST NextObjective with %d treatments but " +
+                            "found only %d distinct OUTPUT port numbers, cannot " +
+                            "translate to ALL groups",
+                    defaultNextTreatments.size(), outPorts.size()),
+                                               ObjectiveError.UNSUPPORTED);
+        }
+
+        final List<GroupBucket> bucketList = outPorts.stream()
+                .map(p -> DefaultTrafficTreatment.builder().setOutput(p).build())
+                .map(DefaultGroupBucket::createAllGroupBucket)
+                .collect(Collectors.toList());
+
+        final int groupId = obj.id();
+        // Use DefaultGroupKey instead of PiGroupKey as we don't have any
+        // action profile to apply to the groups of ALL type.
+        final GroupKey groupKey = new DefaultGroupKey(
+                FabricPipeliner.KRYO.serialize(groupId));
+
+        resultBuilder.addGroup(
+                new DefaultGroupDescription(
+                        deviceId,
+                        GroupDescription.Type.ALL,
+                        new GroupBuckets(bucketList),
+                        groupKey,
+                        groupId,
+                        obj.appId()));
+
+        return groupId;
+    }
+
+    private List<DefaultNextTreatment> defaultNextTreatments(
+            Collection<NextTreatment> nextTreatments, boolean strict)
+            throws FabricPipelinerException {
+        final List<DefaultNextTreatment> defaultNextTreatments = Lists.newArrayList();
+        final List<NextTreatment> unsupportedNextTreatments = Lists.newArrayList();
+        for (NextTreatment n : nextTreatments) {
+            if (n.type() == NextTreatment.Type.TREATMENT) {
+                defaultNextTreatments.add((DefaultNextTreatment) n);
+            } else {
+                unsupportedNextTreatments.add(n);
+            }
+        }
+        if (strict && !unsupportedNextTreatments.isEmpty()) {
+            throw new FabricPipelinerException(format(
+                    "Unsupported NextTreatments: %s",
+                    unsupportedNextTreatments));
+        }
+        return defaultNextTreatments;
+    }
+
+    private TrafficTreatment getFirstDefaultNextTreatmentIfAny(
+            Collection<NextTreatment> nextTreatments)
+            throws FabricPipelinerException {
+        final Collection<DefaultNextTreatment> nexts = defaultNextTreatments(nextTreatments, false);
+        return nexts.isEmpty() ? null : nexts.iterator().next().treatment();
+    }
+
+    private boolean isGroupModifyOp(NextObjective obj) {
+        // If operation is ADD_TO_EXIST or REMOVE_FROM_EXIST, it means we modify
+        // group buckets only, no changes for flow rules.
+        return obj.op() == Objective.Operation.ADD_TO_EXISTING ||
+                obj.op() == Objective.Operation.REMOVE_FROM_EXISTING;
+    }
+
+    private boolean isXconnect(NextObjective obj) {
+        return obj.appId().name().contains(XCONNECT);
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ObjectiveTranslation.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ObjectiveTranslation.java
new file mode 100644
index 0000000..31ff617
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ObjectiveTranslation.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pipelines.fabric.impl.behaviour.pipeliner;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import org.onosproject.net.flow.FlowId;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.group.GroupDescription;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
+
+/**
+ * Result of a pipeliner translation from an objective to flows and groups.
+ */
+final class ObjectiveTranslation {
+
+    private final ImmutableMap<FlowId, FlowRule> flowRules;
+    private final ImmutableMap<Integer, GroupDescription> groups;
+    private final ObjectiveError error;
+
+    private ObjectiveTranslation(Map<FlowId, FlowRule> flowRules,
+                                 Map<Integer, GroupDescription> groups,
+                                 ObjectiveError error) {
+        this.flowRules = ImmutableMap.copyOf(flowRules);
+        this.groups = ImmutableMap.copyOf(groups);
+        this.error = error;
+    }
+
+    /**
+     * Returns flow rules of this translation.
+     *
+     * @return flow rules
+     */
+    Collection<FlowRule> flowRules() {
+        return flowRules.values();
+    }
+
+    /**
+     * Returns groups of this translation.
+     *
+     * @return groups
+     */
+    Collection<GroupDescription> groups() {
+        return groups.values();
+    }
+
+    /**
+     * Returns the error of this translation, is any.
+     *
+     * @return optional error
+     */
+    Optional<ObjectiveError> error() {
+        return Optional.ofNullable(error);
+    }
+
+    /**
+     * Creates a new builder.
+     *
+     * @return the builder
+     */
+    static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Creates a new translation that signals the given error.
+     *
+     * @param error objective error
+     * @return new objective translation
+     */
+    static ObjectiveTranslation ofError(ObjectiveError error) {
+        checkNotNull(error);
+        return new ObjectiveTranslation(
+                Collections.emptyMap(), Collections.emptyMap(), error);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("flowRules", flowRules)
+                .add("groups", groups)
+                .add("error", error)
+                .toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(flowRules, groups, error);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        final ObjectiveTranslation other = (ObjectiveTranslation) obj;
+        return flowRulesExactMatch(other.flowRules)
+                && Objects.equals(this.groups, other.groups)
+                && Objects.equals(this.error, other.error);
+    }
+
+    private boolean flowRulesExactMatch(Map<FlowId, FlowRule> otherFlowRules) {
+        if (otherFlowRules == null || otherFlowRules.size() != this.flowRules.size()) {
+            return false;
+        }
+        return this.flowRules.values().stream()
+                .allMatch(f -> otherFlowRules.containsKey(f.id())
+                        && otherFlowRules.get(f.id()).exactMatch(f));
+    }
+
+    /**
+     * Builder for ObjectiveTranslation. This implementation checks that flow
+     * and groups are not added when an existing one with same ID (FlowId or
+     * GroupId) has already been added.
+     */
+    static final class Builder {
+
+        private final Map<FlowId, FlowRule> flowRules = Maps.newHashMap();
+        private final Map<Integer, GroupDescription> groups = Maps.newHashMap();
+
+        // Hide default constructor
+        private Builder() {
+        }
+
+        /**
+         * Adds a flow rule to this translation.
+         *
+         * @param flowRule flow rule
+         * @return this
+         * @throws FabricPipelinerException if a FlowRule with same FlowId
+         *                                  already exists in this translation
+         */
+        Builder addFlowRule(FlowRule flowRule)
+                throws FabricPipelinerException {
+            checkNotNull(flowRule);
+            if (flowRules.containsKey(flowRule.id())) {
+                final FlowRule existingFlowRule = flowRules.get(flowRule.id());
+                if (!existingFlowRule.exactMatch(flowRule)) {
+                    throw new FabricPipelinerException(format(
+                            "Another FlowRule with same ID has already been " +
+                                    "added to this translation: existing=%s, new=%s",
+                            existingFlowRule, flowRule));
+                }
+            }
+            flowRules.put(flowRule.id(), flowRule);
+            return this;
+        }
+
+        /**
+         * Adds group to this translation.
+         *
+         * @param group group
+         * @return this
+         * @throws FabricPipelinerException if a FlowRule with same GroupId
+         *                                  already exists in this translation
+         */
+        Builder addGroup(GroupDescription group)
+                throws FabricPipelinerException {
+            checkNotNull(group);
+            if (groups.containsKey(group.givenGroupId())) {
+                final GroupDescription existingGroup = groups.get(group.givenGroupId());
+                if (!existingGroup.equals(group)) {
+                    throw new FabricPipelinerException(format(
+                            "Another Group with same ID has already been " +
+                                    "added to this translation: existing=%s, new=%s",
+                            existingGroup, group));
+                }
+            }
+            groups.put(group.givenGroupId(), group);
+            return this;
+        }
+
+        /**
+         * Creates ane translation.
+         *
+         * @return translation instance
+         */
+        ObjectiveTranslation build() {
+            return new ObjectiveTranslation(flowRules, groups, null);
+        }
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/package-info.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/package-info.java
new file mode 100644
index 0000000..905c942
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * Pipeliner implementation classes for fabric.p4.
+ */
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
