diff --git a/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/AbstractCorsaPipeline.java b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/AbstractCorsaPipeline.java
new file mode 100644
index 0000000..2bb521c
--- /dev/null
+++ b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/AbstractCorsaPipeline.java
@@ -0,0 +1,558 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.corsa;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.RemovalCause;
+import com.google.common.cache.RemovalNotification;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.packet.Ethernet;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.NextGroup;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.behaviour.PipelinerContext;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+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.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+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.FlowObjectiveStore;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+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.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupEvent;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupListener;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.meter.MeterService;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.flow.FlowRule.Builder;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Abstraction of the Corsa pipeline handler.
+ */
+public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour implements Pipeliner {
+
+
+    private final Logger log = getLogger(getClass());
+
+    private ServiceDirectory serviceDirectory;
+    protected FlowRuleService flowRuleService;
+    private CoreService coreService;
+    private GroupService groupService;
+    protected MeterService meterService;
+    private FlowObjectiveStore flowObjectiveStore;
+    protected DeviceId deviceId;
+    protected ApplicationId appId;
+    protected DeviceService deviceService;
+
+    private KryoNamespace appKryo = new KryoNamespace.Builder()
+            .register(GroupKey.class)
+            .register(DefaultGroupKey.class)
+            .register(CorsaGroup.class)
+            .register(byte[].class)
+            .build();
+
+    private Cache<GroupKey, NextObjective> pendingGroups;
+
+    private ScheduledExecutorService groupChecker =
+            Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner",
+                    "ovs-corsa-%d"));
+
+    protected static final int CONTROLLER_PRIORITY = 255;
+    protected static final int DROP_PRIORITY = 0;
+    protected static final int HIGHEST_PRIORITY = 0xffff;
+    protected static final String APPID = "org.onosproject.drivers.corsa.CorsaPipeline";
+
+    @Override
+    public void init(DeviceId deviceId, PipelinerContext context) {
+        this.serviceDirectory = context.directory();
+        this.deviceId = deviceId;
+
+        pendingGroups = CacheBuilder.newBuilder()
+                .expireAfterWrite(20, TimeUnit.SECONDS)
+                .removalListener((RemovalNotification<GroupKey, NextObjective> notification) -> {
+                    if (notification.getCause() == RemovalCause.EXPIRED) {
+                        fail(notification.getValue(), ObjectiveError.GROUPINSTALLATIONFAILED);
+                    }
+                }).build();
+
+        groupChecker.scheduleAtFixedRate(new GroupChecker(), 0, 500, TimeUnit.MILLISECONDS);
+
+        coreService = serviceDirectory.get(CoreService.class);
+        flowRuleService = serviceDirectory.get(FlowRuleService.class);
+        groupService = serviceDirectory.get(GroupService.class);
+        meterService = serviceDirectory.get(MeterService.class);
+        deviceService = serviceDirectory.get(DeviceService.class);
+        flowObjectiveStore = context.store();
+
+        groupService.addListener(new InnerGroupListener());
+
+        appId = coreService.registerApplication(APPID);
+
+        initializePipeline();
+    }
+
+    protected abstract void initializePipeline();
+
+    protected void pass(Objective obj) {
+        obj.context().ifPresent(context -> context.onSuccess(obj));
+    }
+
+    protected void fail(Objective obj, ObjectiveError error) {
+        obj.context().ifPresent(context -> context.onError(obj, error));
+    }
+
+    private class GroupChecker implements Runnable {
+
+        @Override
+        public void run() {
+            Set<GroupKey> keys = pendingGroups.asMap().keySet().stream()
+                    .filter(key -> groupService.getGroup(deviceId, key) != null)
+                    .collect(Collectors.toSet());
+
+            keys.stream().forEach(key -> {
+                NextObjective obj = pendingGroups.getIfPresent(key);
+                if (obj == null) {
+                    return;
+                }
+                pass(obj);
+                pendingGroups.invalidate(key);
+                log.info("Heard back from group service for group {}. "
+                        + "Applying pending forwarding objectives", obj.id());
+                flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key));
+            });
+        }
+    }
+
+    private class CorsaGroup implements NextGroup {
+
+        private final GroupKey key;
+
+        public CorsaGroup(GroupKey key) {
+            this.key = key;
+        }
+
+        public GroupKey key() {
+            return key;
+        }
+
+        @Override
+        public byte[] data() {
+            return appKryo.serialize(key);
+        }
+
+    }
+
+    @Override
+    public List<String> getNextMappings(NextGroup nextGroup) {
+        //TODO: to be implemented
+        return Collections.emptyList();
+    }
+
+    private class InnerGroupListener implements GroupListener {
+        @Override
+        public void event(GroupEvent event) {
+            if (event.type() == GroupEvent.Type.GROUP_ADDED) {
+                GroupKey key = event.subject().appCookie();
+
+                NextObjective obj = pendingGroups.getIfPresent(key);
+                if (obj != null) {
+                    flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key));
+                    pass(obj);
+                    pendingGroups.invalidate(key);
+                }
+            }
+        }
+    }
+
+
+    @Override
+    public void filter(FilteringObjective filteringObjective) {
+        if (filteringObjective.type() == FilteringObjective.Type.PERMIT) {
+            processFilter(filteringObjective,
+                    filteringObjective.op() == Objective.Operation.ADD,
+                    filteringObjective.appId());
+        } else {
+            fail(filteringObjective, ObjectiveError.UNSUPPORTED);
+        }
+    }
+
+    private void processFilter(FilteringObjective filt, boolean install,
+                               ApplicationId applicationId) {
+        // This driver only processes filtering criteria defined with switch
+        // ports as the key
+        PortCriterion port;
+        if (!filt.key().equals(Criteria.dummy()) &&
+                filt.key().type() == Criterion.Type.IN_PORT) {
+            port = (PortCriterion) filt.key();
+        } else {
+            log.warn("No key defined in filtering objective from app: {}. Not"
+                    + "processing filtering objective", applicationId);
+            fail(filt, ObjectiveError.UNKNOWN);
+            return;
+        }
+        // convert filtering conditions for switch-intfs into flowrules
+        FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
+        for (Criterion c : filt.conditions()) {
+            if (c.type() == Criterion.Type.ETH_DST) {
+                EthCriterion eth = (EthCriterion) c;
+                FlowRule.Builder rule = processEthFiler(filt, eth, port);
+                rule.forDevice(deviceId)
+                        .fromApp(applicationId);
+                ops = install ? ops.add(rule.build()) : ops.remove(rule.build());
+
+            } else if (c.type() == Criterion.Type.VLAN_VID) {
+                VlanIdCriterion vlan = (VlanIdCriterion) c;
+                FlowRule.Builder rule = processVlanFiler(filt, vlan, port);
+                rule.forDevice(deviceId)
+                        .fromApp(applicationId);
+                ops = install ? ops.add(rule.build()) : ops.remove(rule.build());
+
+            } else if (c.type() == Criterion.Type.IPV4_DST) {
+                IPCriterion ip = (IPCriterion) c;
+                FlowRule.Builder rule = processIpFilter(filt, ip, port);
+                rule.forDevice(deviceId)
+                        .fromApp(applicationId);
+                ops = install ? ops.add(rule.build()) : ops.remove(rule.build());
+
+            } else {
+                log.warn("Driver does not currently process filtering condition"
+                        + " of type: {}", c.type());
+                fail(filt, ObjectiveError.UNSUPPORTED);
+            }
+        }
+        // apply filtering flow rules
+        flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                pass(filt);
+                log.info("Applied filtering rules");
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
+                log.info("Failed to apply filtering rules");
+            }
+        }));
+    }
+
+    protected abstract Builder processEthFiler(FilteringObjective filt,
+                                               EthCriterion eth, PortCriterion port);
+
+    protected abstract Builder processVlanFiler(FilteringObjective filt,
+                                                VlanIdCriterion vlan, PortCriterion port);
+
+    protected abstract Builder processIpFilter(FilteringObjective filt,
+                                               IPCriterion ip, PortCriterion port);
+
+
+    @Override
+    public void forward(ForwardingObjective fwd) {
+        Collection<FlowRule> rules;
+        FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
+
+        rules = processForward(fwd);
+        switch (fwd.op()) {
+            case ADD:
+                rules.stream()
+                        .filter(Objects::nonNull)
+                        .forEach(flowBuilder::add);
+                break;
+            case REMOVE:
+                rules.stream()
+                        .filter(Objects::nonNull)
+                        .forEach(flowBuilder::remove);
+                break;
+            default:
+                fail(fwd, ObjectiveError.UNKNOWN);
+                log.warn("Unknown forwarding type {}", fwd.op());
+        }
+
+        flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                pass(fwd);
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
+            }
+        }));
+
+    }
+
+    private Collection<FlowRule> processForward(ForwardingObjective fwd) {
+        switch (fwd.flag()) {
+            case SPECIFIC:
+                return processSpecific(fwd);
+            case VERSATILE:
+                return processVersatile(fwd);
+            default:
+                fail(fwd, ObjectiveError.UNKNOWN);
+                log.warn("Unknown forwarding flag {}", fwd.flag());
+        }
+        return Collections.emptySet();
+    }
+
+    private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
+        log.debug("Processing specific forwarding objective");
+        TrafficSelector selector = fwd.selector();
+        EthTypeCriterion ethType =
+                (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
+        if (ethType != null) {
+            short et = ethType.ethType().toShort();
+            if (et == Ethernet.TYPE_IPV4) {
+                return processSpecificRoute(fwd);
+            } else if (et == Ethernet.TYPE_VLAN) {
+                /* The ForwardingObjective must specify VLAN ethtype in order to use the Transit Circuit */
+                return processSpecificSwitch(fwd);
+            }
+        }
+
+        fail(fwd, ObjectiveError.UNSUPPORTED);
+        return Collections.emptySet();
+    }
+
+    protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) {
+        /* Not supported by until CorsaPipelineV3 */
+        log.warn("Vlan switching not supported in ovs-corsa driver");
+        fail(fwd, ObjectiveError.UNSUPPORTED);
+        return Collections.emptySet();
+    }
+
+    private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
+        log.debug("Processing vesatile forwarding objective");
+        TrafficSelector selector = fwd.selector();
+
+        EthTypeCriterion ethType =
+                (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
+        if (ethType == null) {
+            log.error("Versatile forwarding objective must include ethType");
+            fail(fwd, ObjectiveError.UNKNOWN);
+            return Collections.emptySet();
+        }
+        Builder rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(fwd.selector())
+                .withTreatment(fwd.treatment())
+                .withPriority(fwd.priority())
+                .fromApp(fwd.appId())
+                .makePermanent();
+        if (ethType.ethType().toShort() == Ethernet.TYPE_ARP) {
+            return processArpTraffic(fwd, rule);
+        } else if (ethType.ethType().toShort() == Ethernet.TYPE_LLDP ||
+                ethType.ethType().toShort() == Ethernet.TYPE_BSN) {
+            return processLinkDiscovery(fwd, rule);
+        } else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
+            return processIpTraffic(fwd, rule);
+        }
+        log.warn("Driver does not support given versatile forwarding objective");
+        fail(fwd, ObjectiveError.UNSUPPORTED);
+        return Collections.emptySet();
+    }
+
+    protected abstract Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, Builder rule);
+
+    protected abstract Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, Builder rule);
+
+    protected abstract Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, Builder rule);
+
+    private Collection<FlowRule> processSpecificRoute(ForwardingObjective fwd) {
+        TrafficSelector filteredSelector =
+                DefaultTrafficSelector.builder()
+                        .matchEthType(Ethernet.TYPE_IPV4)
+                        .matchIPDst(
+                                ((IPCriterion) fwd.selector().getCriterion(Criterion.Type.IPV4_DST)).ip())
+                        .build();
+
+        TrafficTreatment.Builder tb = processSpecificRoutingTreatment();
+
+        if (fwd.nextId() != null) {
+            NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());
+            GroupKey key = appKryo.deserialize(next.data());
+            Group group = groupService.getGroup(deviceId, key);
+            if (group == null) {
+                log.warn("The group left!");
+                fail(fwd, ObjectiveError.GROUPMISSING);
+                return Collections.emptySet();
+            }
+            tb.group(group.id());
+        }
+        Builder ruleBuilder = DefaultFlowRule.builder()
+                .fromApp(fwd.appId())
+                .withPriority(fwd.priority())
+                .forDevice(deviceId)
+                .withSelector(filteredSelector)
+                .withTreatment(tb.build());
+
+        ruleBuilder = processSpecificRoutingRule(ruleBuilder);
+
+        if (fwd.permanent()) {
+            ruleBuilder.makePermanent();
+        } else {
+            ruleBuilder.makeTemporary(fwd.timeout());
+        }
+        return Collections.singletonList(ruleBuilder.build());
+    }
+
+    //Hook for modifying Route traffic treatment
+    protected TrafficTreatment.Builder processSpecificRoutingTreatment() {
+        return DefaultTrafficTreatment.builder();
+    }
+
+    //Hook for modifying Route flow rule
+    protected abstract Builder processSpecificRoutingRule(Builder rb);
+
+    @Override
+    public void next(NextObjective nextObjective) {
+        switch (nextObjective.type()) {
+            case SIMPLE:
+                Collection<TrafficTreatment> treatments = nextObjective.next();
+                if (treatments.size() == 1) {
+                    TrafficTreatment treatment = treatments.iterator().next();
+                    treatment = processNextTreatment(treatment);
+                    GroupBucket bucket =
+                            DefaultGroupBucket.createIndirectGroupBucket(treatment);
+                    final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id()));
+                    GroupDescription groupDescription
+                            = new DefaultGroupDescription(deviceId,
+                            GroupDescription.Type.INDIRECT,
+                            new GroupBuckets(Collections
+                                    .singletonList(bucket)),
+                            key,
+                            null, // let group service determine group id
+                            nextObjective.appId());
+                    groupService.addGroup(groupDescription);
+                    pendingGroups.put(key, nextObjective);
+                }
+                break;
+            case HASHED:
+            case BROADCAST:
+            case FAILOVER:
+                fail(nextObjective, ObjectiveError.UNSUPPORTED);
+                log.warn("Unsupported next objective type {}", nextObjective.type());
+                break;
+            default:
+                fail(nextObjective, ObjectiveError.UNKNOWN);
+                log.warn("Unknown next objective type {}", nextObjective.type());
+        }
+
+    }
+
+    //Hook for altering the NextObjective treatment
+    protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
+        return treatment;
+    }
+
+    //Init helper: Table Miss = Drop
+    protected void processTableMissDrop(boolean install, int table, String description) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        treatment.drop();
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(DROP_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(table).build();
+
+        processFlowRule(install, rule, description);
+    }
+
+    //Init helper: Table Miss = GoTo
+    protected void processTableMissGoTo(boolean install, int table, int goTo, String description) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        treatment.transition(goTo);
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(DROP_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(table).build();
+
+        processFlowRule(install, rule, description);
+    }
+
+    //Init helper: Apply flow rule
+    protected void processFlowRule(boolean install, FlowRule rule, String description) {
+        FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
+        ops = install ? ops.add(rule) : ops.remove(rule);
+
+        flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                log.info(description + " success: " + ops.toString() + ", " + rule.toString());
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                log.info(description + " error: " + ops.toString() + ", " + rule.toString());
+            }
+        }));
+    }
+}
diff --git a/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaDriversLoader.java b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaDriversLoader.java
new file mode 100644
index 0000000..6f2d671
--- /dev/null
+++ b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaDriversLoader.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.corsa;
+
+import org.apache.felix.scr.annotations.Component;
+import org.onosproject.net.driver.AbstractDriverLoader;
+
+/**
+ * Loader for Corsa device drivers.
+ */
+@Component(immediate = true)
+public class CorsaDriversLoader extends AbstractDriverLoader {
+    public CorsaDriversLoader() {
+        super("/corsa-drivers.xml");
+    }
+}
diff --git a/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV1.java b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV1.java
new file mode 100644
index 0000000..ecb5128
--- /dev/null
+++ b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV1.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.corsa;
+
+import org.onlab.packet.Ethernet;
+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.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Driver for Corsa TTP.
+ *
+ */
+public class CorsaPipelineV1 extends OvsCorsaPipeline {
+
+    private final Logger log = getLogger(getClass());
+
+    @Override
+    protected void processVlanMplsTable(boolean install) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment
+                .builder();
+        FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
+        FlowRule rule;
+        // corsa uses non-OF-standard way to match on presence of VLAN tags
+        selector.matchEthType(Ethernet.TYPE_VLAN);
+        treatment.transition(VLAN_TABLE);
+
+        rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(VLAN_MPLS_TABLE).build();
+
+        ops = install ? ops.add(rule) : ops.remove(rule);
+
+        flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                log.info("Provisioned vlan/mpls table");
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                log.info(
+                        "Failed to provision vlan/mpls table");
+            }
+        }));
+    }
+}
diff --git a/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV3.java b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV3.java
new file mode 100644
index 0000000..581a734
--- /dev/null
+++ b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV3.java
@@ -0,0 +1,369 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.corsa;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.DefaultBand;
+import org.onosproject.net.meter.DefaultMeterRequest;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.meter.MeterRequest;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import static org.onosproject.net.flow.FlowRule.Builder;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of the Corsa pipeline handler for pipeline version 3.
+ */
+public class CorsaPipelineV3 extends AbstractCorsaPipeline {
+
+    private final Logger log = getLogger(getClass());
+
+    protected static final int PORT_BASED_PROTO_TABLE = 0;
+    protected static final int VLAN_CHECK_TABLE = 1;
+    protected static final int VLAN_MAC_XLATE_TABLE = 2;
+    protected static final int VLAN_CIRCUIT_TABLE = 3;
+    protected static final int PRIORITY_MAP_TABLE = 4;
+    protected static final int L3_IF_MAC_DA_TABLE = 5;
+    protected static final int ETHER_TABLE = 6;
+    protected static final int FIB_TABLE = 7;
+    protected static final int LOCAL_TABLE = 9;
+
+    protected static final byte MAX_VLAN_PCP = 7;
+
+    protected MeterId defaultMeterId = null;
+
+    @Override
+    protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
+        TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
+
+        treatment.immediate().stream()
+                .filter(i -> {
+                    switch (i.type()) {
+                        case L2MODIFICATION:
+                            L2ModificationInstruction l2i = (L2ModificationInstruction) i;
+                            if (l2i instanceof L2ModificationInstruction.ModVlanIdInstruction ||
+                                    l2i instanceof L2ModificationInstruction.ModEtherInstruction) {
+                                return true;
+                            }
+                        case OUTPUT:
+                            return true;
+                        default:
+                            return false;
+                    }
+                }).forEach(i -> tb.add(i));
+        return tb.build();
+    }
+
+    @Override
+    protected TrafficTreatment.Builder processSpecificRoutingTreatment() {
+        return DefaultTrafficTreatment.builder().deferred();
+    }
+
+    @Override
+    protected Builder processSpecificRoutingRule(Builder rb) {
+        return rb.forTable(FIB_TABLE);
+    }
+
+    @Override
+    protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) {
+        TrafficSelector filteredSelector =
+                DefaultTrafficSelector.builder()
+                        .matchInPort(
+                                ((PortCriterion) fwd.selector().getCriterion(Criterion.Type.IN_PORT)).port())
+                        .matchVlanId(
+                                ((VlanIdCriterion) fwd.selector().getCriterion(Criterion.Type.VLAN_VID)).vlanId())
+                        .build();
+
+        Builder ruleBuilder = DefaultFlowRule.builder()
+                .fromApp(fwd.appId())
+                .withPriority(fwd.priority())
+                .forDevice(deviceId)
+                .withSelector(filteredSelector)
+                .withTreatment(fwd.treatment())
+                .forTable(VLAN_CIRCUIT_TABLE);
+
+        if (fwd.permanent()) {
+            ruleBuilder.makePermanent();
+        } else {
+            ruleBuilder.makeTemporary(fwd.timeout());
+        }
+
+        return Collections.singletonList(ruleBuilder.build());
+    }
+
+    @Override
+    protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, Builder rule) {
+        //TODO
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, Builder rule) {
+        //TODO
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, Builder rule) {
+        //TODO
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected Builder processEthFiler(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
+                         log.debug("adding rule for MAC: {}", eth.mac());
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        selector.matchEthDst(eth.mac());
+        selector.matchInPort(port.port());
+        treatment.transition(ETHER_TABLE);
+        return DefaultFlowRule.builder()
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .makePermanent()
+                .forTable(L3_IF_MAC_DA_TABLE);
+    }
+
+    @Override
+    protected Builder processVlanFiler(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
+        log.debug("adding rule for VLAN: {}", vlan.vlanId());
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        selector.matchVlanId(vlan.vlanId());
+        selector.matchInPort(port.port());
+                /* Static treatment for VLAN_CIRCUIT_TABLE */
+        treatment.setVlanPcp(MAX_VLAN_PCP);
+        treatment.setQueue(0);
+        treatment.meter(MeterId.meterId(defaultMeterId.id())); /* use default meter (Green) */
+        treatment.transition(L3_IF_MAC_DA_TABLE);
+        return DefaultFlowRule.builder()
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .makePermanent()
+                .forTable(VLAN_CIRCUIT_TABLE);
+    }
+
+    @Override
+    protected Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) {
+        log.debug("adding rule for IP: {}", ip.ip());
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ip.ip());
+        treatment.transition(LOCAL_TABLE);
+        return DefaultFlowRule.builder()
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(HIGHEST_PRIORITY)
+                .makePermanent()
+                .forTable(FIB_TABLE);
+    }
+
+    @Override
+    public void initializePipeline() {
+        processMeterTable(true);
+        processPortBasedProtoTable(true); /* Table 0 */
+        processVlanCheckTable(true);      /* Table 1 */
+        processVlanMacXlateTable(true);   /* Table 2 */
+        processVlanCircuitTable(true);    /* Table 3 */
+        processPriorityMapTable(true);    /* Table 4 */
+        processL3IFMacDATable(true);      /* Table 5 */
+        processEtherTable(true);          /* Table 6 */
+        processFibTable(true);            /* Table 7 */
+        processLocalTable(true);          /* Table 9 */
+    }
+
+    protected void processMeterTable(boolean install) {
+        //Green meter : Pass all traffic
+        Band dropBand = DefaultBand.builder()
+                .ofType(Band.Type.DROP)
+                .withRate(0xFFFFFFFF)   /* Max Rate */
+                .build();
+        MeterRequest.Builder ops = DefaultMeterRequest.builder()
+                .forDevice(deviceId)
+                .withBands(Collections.singletonList(dropBand))
+                .fromApp(appId);
+
+        Meter meter = meterService.submit(install ? ops.add() : ops.remove());
+        defaultMeterId = meter.id();
+    }
+
+    protected void processPortBasedProtoTable(boolean install) {
+        /* Default action */
+        processTableMissGoTo(install, PORT_BASED_PROTO_TABLE, VLAN_CHECK_TABLE, "Provisioned port-based table");
+    }
+
+    protected void processVlanCheckTable(boolean install) {
+
+        /* Default action */
+        processTableMissDrop(install, VLAN_CHECK_TABLE, "Provisioned vlantable drop");
+
+        processTaggedPackets(install);
+
+    }
+
+    /* Tagged packets to VLAN_MAC_XLATE */
+    protected void processTaggedPackets(boolean install) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VlanId.ANY);
+
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        treatment.transition(VLAN_MAC_XLATE_TABLE);
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(VLAN_CHECK_TABLE).build();
+        processFlowRule(install, rule, "Provisioned vlan table tagged packets");
+    }
+
+    protected void processVlanMacXlateTable(boolean install) {
+        /* Default action */
+        processTableMissGoTo(install, VLAN_MAC_XLATE_TABLE, VLAN_CIRCUIT_TABLE, "Provisioned vlan mac table");
+    }
+
+    protected void processVlanCircuitTable(boolean install) {
+        /* Default action */
+        processTableMissDrop(install, VLAN_CIRCUIT_TABLE, "Provisioned vlan circuit");
+    }
+
+    private void processPriorityMapTable(boolean install) {
+        /* Not required currently */
+    }
+
+    protected void processL3IFMacDATable(boolean install) {
+        int table = L3_IF_MAC_DA_TABLE;
+
+        /* Default action */
+        processTableMissDrop(install, table, "Provisioned l3 table drop");
+
+        /* Allow MAC broadcast frames on all ports */
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchEthDst(MacAddress.BROADCAST);
+
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        treatment.transition(ETHER_TABLE);
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(table).build();
+        processFlowRule(install, rule, "Provisioned l3 table");
+    }
+
+
+    protected void processEtherTable(boolean install) {
+        int table = ETHER_TABLE;
+
+        /* Default action */
+        processTableMissDrop(install, table, "Provisioned ether type table drop");
+
+        /* Arp to controller */
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(Ethernet.TYPE_ARP);
+
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        treatment.punt();
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(table).build();
+        processFlowRule(install, rule, "Provisioned ether type table arp");
+
+        /* IP to FIB_TABLE */
+        selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+
+        treatment = DefaultTrafficTreatment.builder();
+        treatment.transition(FIB_TABLE);
+
+        rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(table).build();
+        processFlowRule(install, rule, "Provisioned ether type table ip");
+    }
+
+    private void processFibTable(boolean install) {
+        /* Default action */
+        processTableMissDrop(install, FIB_TABLE, "Provisioned fib drop");
+    }
+
+    private void processLocalTable(boolean install) {
+        int table = LOCAL_TABLE;
+        /* Default action */
+        processTableMissDrop(install, table, "Provisioned local table drop");
+
+        /* Send all protocols to controller */
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        treatment.punt();
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(table).build();
+        processFlowRule(install, rule, "Provisioned ether type table to controller");
+    }
+
+
+}
diff --git a/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV39.java b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV39.java
new file mode 100644
index 0000000..e9a331a
--- /dev/null
+++ b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV39.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.corsa;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.IPProtocolCriterion;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import static org.onosproject.net.flow.FlowRule.Builder;
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class CorsaPipelineV39 extends CorsaPipelineV3 {
+
+    private final Logger log = getLogger(getClass());
+
+    private static final Short NATIVE_VLAN = 4095;
+
+    @Override
+    public void initializePipeline() {
+
+        processMeterTable(true);           //Meter Table
+        processPortBasedProtoTable(true);
+        processVlanCheckTable(true);       //Table 1
+        processVlanMacXlateTable(true);    //Table 2
+        processVlanCircuitTable(true);     //Table 3
+        processL3IFMacDATable(true);       //Table 5
+        processEtherTable(true);           //Table 6
+        //TODO: to be implemented for intents
+        //processFibTable(true);           //Table 7
+        //processLocalTable(true);         //Table 9
+    }
+
+    @Override
+    protected void processVlanCheckTable(boolean install) {
+        //FIXME: error
+        processTableMissGoTo(true, VLAN_CHECK_TABLE, VLAN_MAC_XLATE_TABLE, "Provisioned vlan tagged");
+        //Tag untagged packets
+        processUntaggedPackets(install);
+
+    }
+
+    private void processUntaggedPackets(boolean install) {
+
+        deviceService.getPorts(deviceId).forEach(port -> {
+            if (!port.number().isLogical()) {
+
+                TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+                        .pushVlan().setVlanId(VlanId.vlanId(NATIVE_VLAN))
+                        .transition(VLAN_MAC_XLATE_TABLE);
+
+                TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
+                        .matchVlanId(VlanId.NONE)
+                        .matchInPort(port.number());
+
+                Builder rule = DefaultFlowRule.builder()
+                        .forDevice(deviceId)
+                        .withTreatment(treatment.build())
+                        .withSelector(selector.build())
+                        .withPriority(CONTROLLER_PRIORITY)
+                        .fromApp(appId)
+                        .makePermanent()
+                        .forTable(VLAN_CHECK_TABLE);
+
+                processFlowRule(install, rule.build(), "Provisioned vlan untagged packet table");
+            }
+        });
+    }
+
+    @Override
+    protected void processVlanCircuitTable(boolean install) {
+        //Default action
+        processTableMissDrop(install, VLAN_CIRCUIT_TABLE, "Provisioned vlan circuit table drop");
+        //FIXME: it should be done only per port based when intent is installed
+        //Manage untagged packets
+        processRouterPacket(install);
+    }
+
+    private void processRouterPacket(boolean install) {
+
+        deviceService.getPorts(deviceId).forEach(port -> {
+            if (!port.number().isLogical()) {
+                TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
+                        .matchVlanId(VlanId.vlanId(NATIVE_VLAN))
+                        .matchInPort(port.number());
+
+                TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+                        .setVlanPcp((byte) 0)
+                        .setQueue(0)
+                        .meter(defaultMeterId)
+                        .transition(L3_IF_MAC_DA_TABLE);
+
+                FlowRule rule = DefaultFlowRule.builder()
+                        .forDevice(deviceId)
+                        .withSelector(selector.build())
+                        .withTreatment(treatment.build())
+                        .withPriority(CONTROLLER_PRIORITY)
+                        .fromApp(appId)
+                        .makePermanent()
+                        .forTable(VLAN_CIRCUIT_TABLE).build();
+                processFlowRule(install, rule, "Provisioned vlan circuit table");
+            }
+        });
+    }
+
+    @Override
+    protected void processL3IFMacDATable(boolean install) {
+        int table = L3_IF_MAC_DA_TABLE;
+
+        //Default action
+        processTableMissDrop(install, table, "Provisioned l3 table drop");
+
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+                .transition(ETHER_TABLE);
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(1)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(table).build();
+        processFlowRule(install, rule, "Provisioned l3 table");
+    }
+
+    protected void processEtherTable(boolean install) {
+
+        //Default action
+        processTableMissDrop(install, ETHER_TABLE, "Provisioned ether type table drop");
+
+        //IP to FIB_TABLE
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4);
+
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder().transition(FIB_TABLE);
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(ETHER_TABLE).build();
+        processFlowRule(install, rule, "Provisioned ether type table ip");
+    }
+
+    @Override
+    protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, Builder rule) {
+        rule.forTable(PORT_BASED_PROTO_TABLE);
+        rule.withPriority(255);
+        return Collections.singletonList(rule.build());
+    }
+
+    @Override
+    protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, Builder rule) {
+        rule.forTable(PORT_BASED_PROTO_TABLE);
+        rule.withPriority(255);
+        return Collections.singletonList(rule.build());
+    }
+
+    @Override
+    protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, Builder rule) {
+        IPCriterion ipSrc = (IPCriterion) fwd.selector()
+                .getCriterion(Criterion.Type.IPV4_SRC);
+        if (ipSrc != null) {
+            log.warn("Driver does not currently handle matching Src IP");
+            fail(fwd, ObjectiveError.UNSUPPORTED);
+            return Collections.emptySet();
+        }
+        IPCriterion ipDst = (IPCriterion) fwd.selector()
+                .getCriterion(Criterion.Type.IPV4_DST);
+        if (ipDst != null) {
+            log.error("Driver handles Dst IP matching as specific forwarding "
+                    + "objective, not versatile");
+            fail(fwd, ObjectiveError.UNSUPPORTED);
+            return Collections.emptySet();
+        }
+        IPProtocolCriterion ipProto = (IPProtocolCriterion) fwd.selector()
+                .getCriterion(Criterion.Type.IP_PROTO);
+        if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) {
+            log.warn("Driver automatically punts all packets reaching the "
+                    + "LOCAL table to the controller");
+            pass(fwd);
+            return Collections.emptySet();
+        }
+        return Collections.emptySet();
+    }
+}
diff --git a/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaSwitchHandshaker.java b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaSwitchHandshaker.java
new file mode 100644
index 0000000..6232c30
--- /dev/null
+++ b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaSwitchHandshaker.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.corsa;
+
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
+import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
+import org.projectfloodlight.openflow.protocol.OFFlowMod;
+import org.projectfloodlight.openflow.protocol.OFGroupMod;
+import org.projectfloodlight.openflow.protocol.OFGroupType;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFMeterMod;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.types.OFGroup;
+import org.projectfloodlight.openflow.types.TableId;
+
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+
+/**
+ * Corsa switch handshaker.
+ */
+public class CorsaSwitchHandshaker extends AbstractOpenFlowSwitch {
+
+    private AtomicBoolean handshakeComplete = new AtomicBoolean(false);
+
+    private int barrierXid;
+
+
+    @Override
+    public Boolean supportNxRole() {
+        return false;
+    }
+
+    @Override
+    public void startDriverHandshake() {
+        if (startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeAlreadyStarted();
+        }
+        startDriverHandshakeCalled = true;
+        OFFlowMod fm = factory().buildFlowDelete()
+                .setTableId(TableId.ALL)
+                .setOutGroup(OFGroup.ANY)
+                .build();
+
+        sendMsg(Collections.singletonList(fm));
+
+        OFGroupMod gm = factory().buildGroupDelete()
+                .setGroup(OFGroup.ALL)
+                .setGroupType(OFGroupType.ALL)
+                .build();
+
+        sendMsg(Collections.singletonList(gm));
+
+        OFMeterMod mm = factory().buildMeterMod()
+                .setMeterId(MeterId.ALL.id())
+                .build();
+
+        sendMsg(Collections.singletonList(mm));
+
+        barrierXid = getNextTransactionId();
+        OFBarrierRequest barrier = factory().buildBarrierRequest()
+                .setXid(barrierXid).build();
+
+
+        sendHandshakeMessage(barrier);
+
+    }
+
+    @Override
+    public boolean isDriverHandshakeComplete() {
+        if (!startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeAlreadyStarted();
+        }
+        return handshakeComplete.get();
+    }
+
+    @Override
+    public void processDriverHandshakeMessage(OFMessage m) {
+        if (!startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeNotStarted();
+        }
+        if (handshakeComplete.get()) {
+            throw new SwitchDriverSubHandshakeCompleted(m);
+        }
+        if (m.getType() == OFType.BARRIER_REPLY &&
+                m.getXid() == barrierXid) {
+            handshakeComplete.set(true);
+        }
+    }
+
+}
diff --git a/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/OvsCorsaPipeline.java b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/OvsCorsaPipeline.java
new file mode 100644
index 0000000..e291be1
--- /dev/null
+++ b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/OvsCorsaPipeline.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.corsa;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+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.FlowRuleOperations;
+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.IPProtocolCriterion;
+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.ForwardingObjective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * OpenvSwitch emulation of the Corsa pipeline handler.
+ */
+public class OvsCorsaPipeline extends AbstractCorsaPipeline {
+
+    private final Logger log = getLogger(getClass());
+
+    protected static final int MAC_TABLE = 0;
+    protected static final int VLAN_MPLS_TABLE = 1;
+    protected static final int VLAN_TABLE = 2;
+    //protected static final int MPLS_TABLE = 3;
+    protected static final int ETHER_TABLE = 4;
+    protected static final int COS_MAP_TABLE = 5;
+    protected static final int FIB_TABLE = 6;
+    protected static final int LOCAL_TABLE = 9;
+
+    @Override
+    protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, FlowRule.Builder rule) {
+        log.warn("Driver automatically handles ARP packets by punting to controller "
+                + " from ETHER table");
+        pass(fwd);
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, FlowRule.Builder rule) {
+        log.warn("Driver currently does not currently handle LLDP packets");
+        fail(fwd, ObjectiveError.UNSUPPORTED);
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, FlowRule.Builder rule) {
+        IPCriterion ipSrc = (IPCriterion) fwd.selector()
+                .getCriterion(Criterion.Type.IPV4_SRC);
+        if (ipSrc != null) {
+            log.warn("Driver does not currently handle matching Src IP");
+            fail(fwd, ObjectiveError.UNSUPPORTED);
+            return Collections.emptySet();
+        }
+        IPCriterion ipDst = (IPCriterion) fwd.selector()
+                .getCriterion(Criterion.Type.IPV4_DST);
+        if (ipDst != null) {
+            log.error("Driver handles Dst IP matching as specific forwarding "
+                    + "objective, not versatile");
+            fail(fwd, ObjectiveError.UNSUPPORTED);
+            return Collections.emptySet();
+        }
+        IPProtocolCriterion ipProto = (IPProtocolCriterion) fwd.selector()
+                .getCriterion(Criterion.Type.IP_PROTO);
+        if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) {
+            log.warn("Driver automatically punts all packets reaching the "
+                    + "LOCAL table to the controller");
+            pass(fwd);
+            return Collections.emptySet();
+        }
+        return Collections.emptySet();
+    }
+
+    @Override
+    protected FlowRule.Builder processSpecificRoutingRule(FlowRule.Builder rb) {
+        return rb.forTable(FIB_TABLE);
+    }
+
+    @Override
+    protected FlowRule.Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) {
+        log.debug("adding rule for IP: {}", ip.ip());
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ip.ip());
+        treatment.transition(LOCAL_TABLE);
+        return DefaultFlowRule.builder()
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(HIGHEST_PRIORITY)
+                .makePermanent()
+                .forTable(FIB_TABLE);
+    }
+
+    @Override
+    protected FlowRule.Builder processVlanFiler(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
+        log.debug("adding rule for VLAN: {}", vlan.vlanId());
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        selector.matchVlanId(vlan.vlanId());
+        selector.matchInPort(port.port());
+        treatment.transition(ETHER_TABLE);
+        treatment.deferred().popVlan();
+        return DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .makePermanent()
+                .forTable(VLAN_TABLE);
+    }
+
+
+    protected FlowRule.Builder processEthFiler(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
+        log.debug("adding rule for MAC: {}", eth.mac());
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        selector.matchEthDst(eth.mac());
+        treatment.transition(VLAN_MPLS_TABLE);
+        return DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .makePermanent()
+                .forTable(MAC_TABLE);
+    }
+
+    @Override
+    protected void initializePipeline() {
+        processMacTable(true);
+        processVlanMplsTable(true);
+        processVlanTable(true);
+        processEtherTable(true);
+        processCosTable(true);
+        processFibTable(true);
+        processLocalTable(true);
+    }
+
+    private void processMacTable(boolean install) {
+        TrafficSelector.Builder selector;
+        TrafficTreatment.Builder treatment;
+
+        // Bcast rule
+        selector = DefaultTrafficSelector.builder();
+        treatment = DefaultTrafficTreatment.builder();
+
+        selector.matchEthDst(MacAddress.BROADCAST);
+        treatment.transition(VLAN_MPLS_TABLE);
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(MAC_TABLE).build();
+        processFlowRule(true, rule, "Provisioned mac table transition");
+
+        //Drop rule
+        processTableMissDrop(true, MAC_TABLE, "Provisioned mac table drop action");
+
+    }
+
+    protected void processVlanMplsTable(boolean install) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment
+                .builder();
+        FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
+        FlowRule rule;
+
+        selector.matchVlanId(VlanId.ANY);
+        treatment.transition(VLAN_TABLE);
+
+        rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(VLAN_MPLS_TABLE).build();
+
+        processFlowRule(true, rule, "Provisioned vlan/mpls table");
+    }
+
+    private void processVlanTable(boolean install) {
+        processTableMissDrop(true, VLAN_TABLE, "Provisioned vlan table");
+    }
+
+    private void processEtherTable(boolean install) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
+        .matchEthType(Ethernet.TYPE_ARP);
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment
+                .builder()
+                .punt();
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(ETHER_TABLE).build();
+
+        processFlowRule(true, rule, "Provisioned ether table");
+        selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4);
+        treatment = DefaultTrafficTreatment.builder()
+        .transition(COS_MAP_TABLE);
+
+        rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withPriority(CONTROLLER_PRIORITY)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(ETHER_TABLE).build();
+        processFlowRule(true, rule, "Provisioned ether table");
+
+        //Drop rule
+        processTableMissDrop(true, VLAN_TABLE, "Provisioned ether table");
+
+    }
+
+    private void processCosTable(boolean install) {
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment
+                .builder()
+                .transition(FIB_TABLE);
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(DROP_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(COS_MAP_TABLE).build();
+        processFlowRule(true, rule, "Provisioned cos table");
+
+    }
+
+    private void processFibTable(boolean install) {
+        processTableMissDrop(true, FIB_TABLE, "Provisioned FIB table");
+    }
+
+    private void processLocalTable(boolean install) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment
+                .builder()
+        .punt();
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(CONTROLLER_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(LOCAL_TABLE).build();
+
+        processFlowRule(true, rule, "Provisioned Local table");
+    }
+
+
+}
diff --git a/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/package-info.java b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/package-info.java
new file mode 100644
index 0000000..1a6d903
--- /dev/null
+++ b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Corsa drivers.
+ */
+package org.onosproject.drivers.corsa;
\ No newline at end of file
