diff --git a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumSdnRoadmFlowRuleProgrammable.java b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumSdnRoadmFlowRuleProgrammable.java
new file mode 100644
index 0000000..7dde491
--- /dev/null
+++ b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumSdnRoadmFlowRuleProgrammable.java
@@ -0,0 +1,409 @@
+/*
+ * 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.lumentum;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.lang3.tuple.Pair;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.GridType;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.OchSignalType;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowId;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleProgrammable;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.snmp4j.PDU;
+import org.snmp4j.event.ResponseEvent;
+import org.snmp4j.smi.Integer32;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.UnsignedInteger32;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.util.TreeEvent;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+// TODO: need to convert between OChSignal and XC channel number
+public class LumentumSdnRoadmFlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
+
+    private static final Logger log =
+            LoggerFactory.getLogger(LumentumSdnRoadmFlowRuleProgrammable.class);
+
+    // Default values
+    private static final int DEFAULT_TARGET_GAIN_PREAMP = 150;
+    private static final int DEFAULT_TARGET_GAIN_BOOSTER = 200;
+    private static final int DISABLE_CHANNEL_TARGET_POWER = -650;
+    private static final int DEFAULT_CHANNEL_TARGET_POWER = -30;
+    private static final int DISABLE_CHANNEL_ABSOLUTE_ATTENUATION = 160;
+    private static final int DEFAULT_CHANNEL_ABSOLUTE_ATTENUATION = 50;
+    private static final int DISABLE_CHANNEL_ADD_DROP_PORT_INDEX = 1;
+    private static final int OUT_OF_SERVICE = 1;
+    private static final int IN_SERVICE = 2;
+    private static final int OPEN_LOOP = 1;
+    private static final int CLOSED_LOOP = 2;
+    // First 20 ports are add/mux ports, next 20 are drop/demux
+    private static final int DROP_PORT_OFFSET = 20;
+
+    // OIDs
+    private static final String CTRL_AMP_MODULE_SERVICE_STATE_PREAMP = ".1.3.6.1.4.1.46184.1.4.4.1.2.1";
+    private static final String CTRL_AMP_MODULE_SERVICE_STATE_BOOSTER = ".1.3.6.1.4.1.46184.1.4.4.1.2.2";
+    private static final String CTRL_AMP_MODULE_TARGET_GAIN_PREAMP = ".1.3.6.1.4.1.46184.1.4.4.1.8.1";
+    private static final String CTRL_AMP_MODULE_TARGET_GAIN_BOOSTER = ".1.3.6.1.4.1.46184.1.4.4.1.8.2";
+    private static final String CTRL_CHANNEL_STATE = ".1.3.6.1.4.1.46184.1.4.2.1.3.";
+    private static final String CTRL_CHANNEL_MODE = ".1.3.6.1.4.1.46184.1.4.2.1.4.";
+    private static final String CTRL_CHANNEL_TARGET_POWER = ".1.3.6.1.4.1.46184.1.4.2.1.6.";
+    private static final String CTRL_CHANNEL_ADD_DROP_PORT_INDEX = ".1.3.6.1.4.1.46184.1.4.2.1.13.";
+    private static final String CTRL_CHANNEL_ABSOLUTE_ATTENUATION = ".1.3.6.1.4.1.46184.1.4.2.1.5.";
+
+    private LumentumSnmpDevice snmp;
+
+    @Override
+    public Collection<FlowEntry> getFlowEntries() {
+        try {
+            snmp = new LumentumSnmpDevice(handler().data().deviceId());
+        } catch (IOException e) {
+            log.error("Failed to connect to device: ", e);
+            return Collections.emptyList();
+        }
+
+        // Line in is last but one port, line out is last
+        DeviceService deviceService = this.handler().get(DeviceService.class);
+        List<Port> ports = deviceService.getPorts(data().deviceId());
+        if (ports.size() < 2) {
+            return Collections.emptyList();
+        }
+        PortNumber lineIn = ports.get(ports.size() - 2).number();
+        PortNumber lineOut = ports.get(ports.size() - 1).number();
+
+        Collection<FlowEntry> entries = Lists.newLinkedList();
+
+        // Add rules
+        OID addOid = new OID(CTRL_CHANNEL_STATE + "1");
+        entries.addAll(
+                fetchRules(addOid, true, lineOut).stream()
+                        .map(fr -> new DefaultFlowEntry(fr, FlowEntry.FlowEntryState.ADDED, 0, 0, 0))
+                        .collect(Collectors.toList())
+        );
+
+        // Drop rules
+        OID dropOid = new OID(CTRL_CHANNEL_STATE + "2");
+        entries.addAll(
+                fetchRules(dropOid, false, lineIn).stream()
+                        .map(fr -> new DefaultFlowEntry(fr, FlowEntry.FlowEntryState.ADDED, 0, 0, 0))
+                        .collect(Collectors.toList())
+        );
+
+        return entries;
+    }
+
+    @Override
+    public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
+        try {
+            snmp = new LumentumSnmpDevice(data().deviceId());
+        } catch (IOException e) {
+            log.error("Failed to connect to device: ", e);
+        }
+
+        // Line ports
+        DeviceService deviceService = this.handler().get(DeviceService.class);
+        List<Port> ports = deviceService.getPorts(data().deviceId());
+        List<PortNumber> linePorts = ports.subList(ports.size() - 2, ports.size()).stream()
+                .map(p -> p.number())
+                .collect(Collectors.toList());
+
+        // Apply the valid rules on the device
+        Collection<FlowRule> added = rules.stream()
+                .map(r -> new CrossConnectFlowRule(r, linePorts))
+                .filter(xc -> installCrossConnect(xc))
+                .collect(Collectors.toList());
+
+        // Cache the cookie/priority
+        CrossConnectCache cache = this.handler().get(CrossConnectCache.class);
+        added.forEach(xc -> cache.set(
+                Objects.hash(data().deviceId(), xc.selector(), xc.treatment()),
+                xc.id(),
+                xc.priority()));
+
+        return added;
+    }
+
+    @Override
+    public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
+        try {
+            snmp = new LumentumSnmpDevice(data().deviceId());
+        } catch (IOException e) {
+            log.error("Failed to connect to device: ", e);
+        }
+
+        // Line ports
+        DeviceService deviceService = this.handler().get(DeviceService.class);
+        List<Port> ports = deviceService.getPorts(data().deviceId());
+        List<PortNumber> linePorts = ports.subList(ports.size() - 2, ports.size()).stream()
+                .map(p -> p.number())
+                .collect(Collectors.toList());
+
+        // Apply the valid rules on the device
+        Collection<FlowRule> removed = rules.stream()
+                .map(r -> new CrossConnectFlowRule(r, linePorts))
+                .filter(xc -> removeCrossConnect(xc))
+                .collect(Collectors.toList());
+
+        // Remove flow rule from cache
+        CrossConnectCache cache = this.handler().get(CrossConnectCache.class);
+        removed.forEach(xc -> cache.remove(
+                Objects.hash(data().deviceId(), xc.selector(), xc.treatment())));
+
+        return removed;
+    }
+
+    // Installs cross connect on device
+    private boolean installCrossConnect(CrossConnectFlowRule xc) {
+
+        int channel = toChannel(xc.ochSignal());
+        long addDrop = xc.addDrop().toLong();
+        if (!xc.isAddRule()) {
+            addDrop -= DROP_PORT_OFFSET;
+        }
+
+        // Create the PDU object
+        PDU pdu = new PDU();
+        pdu.setType(PDU.SET);
+
+        // Enable preamp & booster
+        List<OID> oids = Arrays.asList(new OID(CTRL_AMP_MODULE_SERVICE_STATE_PREAMP),
+                new OID(CTRL_AMP_MODULE_SERVICE_STATE_BOOSTER));
+        oids.forEach(
+                oid -> pdu.add(new VariableBinding(oid, new Integer32(IN_SERVICE)))
+        );
+
+        // Set target gain on preamp & booster
+        OID ctrlAmpModuleTargetGainPreamp = new OID(CTRL_AMP_MODULE_TARGET_GAIN_PREAMP);
+        pdu.add(new VariableBinding(ctrlAmpModuleTargetGainPreamp, new Integer32(DEFAULT_TARGET_GAIN_PREAMP)));
+        OID ctrlAmpModuleTargetGainBooster = new OID(CTRL_AMP_MODULE_TARGET_GAIN_BOOSTER);
+        pdu.add(new VariableBinding(ctrlAmpModuleTargetGainBooster, new Integer32(DEFAULT_TARGET_GAIN_BOOSTER)));
+
+        // Make cross connect
+        OID ctrlChannelAddDropPortIndex = new OID(CTRL_CHANNEL_ADD_DROP_PORT_INDEX +
+                (xc.isAddRule() ? "1." : "2.") + channel);
+        pdu.add(new VariableBinding(ctrlChannelAddDropPortIndex, new UnsignedInteger32(addDrop)));
+
+        // Add rules use closed loop, drop rules open loop
+        // Add rules are set to target power, drop rules are attenuated
+        if (xc.isAddRule()) {
+            OID ctrlChannelMode = new OID(CTRL_CHANNEL_MODE + "1." + channel);
+            pdu.add(new VariableBinding(ctrlChannelMode, new Integer32(CLOSED_LOOP)));
+
+            OID ctrlChannelTargetPower = new OID(CTRL_CHANNEL_TARGET_POWER + "1." + channel);
+            pdu.add(new VariableBinding(ctrlChannelTargetPower, new Integer32(DEFAULT_CHANNEL_TARGET_POWER)));
+        } else {
+            OID ctrlChannelMode = new OID(CTRL_CHANNEL_MODE + "2." + channel);
+            pdu.add(new VariableBinding(ctrlChannelMode, new Integer32(OPEN_LOOP)));
+
+            OID ctrlChannelAbsoluteAttenuation = new OID(CTRL_CHANNEL_ABSOLUTE_ATTENUATION + "2." + channel);
+            pdu.add(new VariableBinding(
+                    ctrlChannelAbsoluteAttenuation, new UnsignedInteger32(DEFAULT_CHANNEL_ABSOLUTE_ATTENUATION)));
+        }
+
+        // Final step is to enable the channel
+        OID ctrlChannelState = new OID(CTRL_CHANNEL_STATE + (xc.isAddRule() ? "1." : "2.") + channel);
+        pdu.add(new VariableBinding(ctrlChannelState, new Integer32(IN_SERVICE)));
+
+        try {
+            ResponseEvent response = snmp.set(pdu);
+
+             // TODO: parse response
+        } catch (IOException e) {
+            log.error("Failed to create cross connect, unable to connect to device: ", e);
+        }
+
+        return true;
+    }
+
+    // Removes cross connect on device
+    private boolean removeCrossConnect(CrossConnectFlowRule xc) {
+
+        int channel = toChannel(xc.ochSignal());
+
+        // Create the PDU object
+        PDU pdu = new PDU();
+        pdu.setType(PDU.SET);
+
+        // Disable the channel
+        OID ctrlChannelState = new OID(CTRL_CHANNEL_STATE + (xc.isAddRule() ? "1." : "2.") + channel);
+        pdu.add(new VariableBinding(ctrlChannelState, new Integer32(OUT_OF_SERVICE)));
+
+        // Put cross connect back into default port 1
+        OID ctrlChannelAddDropPortIndex = new OID(CTRL_CHANNEL_ADD_DROP_PORT_INDEX +
+                (xc.isAddRule() ? "1." : "2.") + channel);
+        pdu.add(new VariableBinding(ctrlChannelAddDropPortIndex,
+                new UnsignedInteger32(DISABLE_CHANNEL_ADD_DROP_PORT_INDEX)));
+
+        // Put port/channel back to open loop
+        OID ctrlChannelMode = new OID(CTRL_CHANNEL_MODE + (xc.isAddRule() ? "1." : "2.") + channel);
+        pdu.add(new VariableBinding(ctrlChannelMode, new Integer32(OPEN_LOOP)));
+
+        // Add rules are set to target power, drop rules are attenuated
+        if (xc.isAddRule()) {
+            OID ctrlChannelTargetPower = new OID(CTRL_CHANNEL_TARGET_POWER + "1." + channel);
+            pdu.add(new VariableBinding(ctrlChannelTargetPower, new Integer32(DISABLE_CHANNEL_TARGET_POWER)));
+        } else {
+            OID ctrlChannelAbsoluteAttenuation = new OID(CTRL_CHANNEL_ABSOLUTE_ATTENUATION + "2." + channel);
+            pdu.add(new VariableBinding(
+                    ctrlChannelAbsoluteAttenuation, new UnsignedInteger32(DISABLE_CHANNEL_ABSOLUTE_ATTENUATION)));
+        }
+
+        try {
+            ResponseEvent response = snmp.set(pdu);
+
+            // TODO: parse response
+        } catch (IOException e) {
+            log.error("Failed to remove cross connect, unable to connect to device: ", e);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Convert OCh signal to Lumentum channel ID.
+     *
+     * @param ochSignal OCh signal
+     * @return Lumentum channel ID
+     */
+    public static int toChannel(OchSignal ochSignal) {
+        // FIXME: move to cross connect validation
+        checkArgument(ochSignal.channelSpacing() == ChannelSpacing.CHL_50GHZ);
+        checkArgument(LumentumSnmpDevice.START_CENTER_FREQ.compareTo(ochSignal.centralFrequency()) <= 0);
+        checkArgument(LumentumSnmpDevice.END_CENTER_FREQ.compareTo(ochSignal.centralFrequency()) >= 0);
+
+        return ochSignal.spacingMultiplier() + LumentumSnmpDevice.MULTIPLIER_SHIFT;
+    }
+
+    /**
+     * Convert Lumentum channel ID to OCh signal.
+     *
+     * @param channel Lumentum channel ID
+     * @return OCh signal
+     */
+    public static OchSignal toOchSignal(int channel) {
+        checkArgument(1 <= channel);
+        checkArgument(channel <= 96);
+
+        return new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ,
+                channel - LumentumSnmpDevice.MULTIPLIER_SHIFT, 4);
+    }
+
+    // Returns the currently configured add/drop port for the given channel.
+    private PortNumber getAddDropPort(int channel, boolean isAddPort) {
+        OID oid = new OID(CTRL_CHANNEL_ADD_DROP_PORT_INDEX + (isAddPort ? "1" : "2"));
+
+        for (TreeEvent event : snmp.get(oid)) {
+            if (event == null) {
+                return null;
+            }
+
+            VariableBinding[] varBindings = event.getVariableBindings();
+
+            for (VariableBinding varBinding : varBindings) {
+                if (varBinding.getOid().last() == channel) {
+                    int port = varBinding.getVariable().toInt();
+                    if (!isAddPort) {
+                        port += DROP_PORT_OFFSET;
+                    }
+                    return PortNumber.portNumber(port);
+
+                }
+            }
+
+        }
+
+        return null;
+    }
+
+    // Returns the currently installed flow entries on the device.
+    private List<FlowRule> fetchRules(OID oid, boolean isAdd, PortNumber linePort) {
+        List<FlowRule> rules = new LinkedList<>();
+
+        for (TreeEvent event : snmp.get(oid)) {
+            if (event == null) {
+                continue;
+            }
+
+            VariableBinding[] varBindings = event.getVariableBindings();
+            for (VariableBinding varBinding : varBindings) {
+                CrossConnectCache cache = this.handler().get(CrossConnectCache.class);
+
+                if (varBinding.getVariable().toInt() == IN_SERVICE) {
+                    int channel = varBinding.getOid().removeLast();
+
+                    PortNumber addDropPort = getAddDropPort(channel, isAdd);
+                    if (addDropPort == null) {
+                        continue;
+                    }
+
+                    TrafficSelector selector = DefaultTrafficSelector.builder()
+                            .matchInPort(isAdd ? addDropPort : linePort)
+                            .add(Criteria.matchOchSignalType(OchSignalType.FIXED_GRID))
+                            .add(Criteria.matchLambda(toOchSignal(channel)))
+                            .build();
+                    TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                            .setOutput(isAdd ? linePort : addDropPort)
+                            .build();
+
+                    // Lookup flow ID and priority
+                    int hash = Objects.hash(data().deviceId(), selector, treatment);
+                    Pair<FlowId, Integer> lookup = cache.get(hash);
+                    if (lookup == null) {
+                        continue;
+                    }
+
+                    FlowRule fr = DefaultFlowRule.builder()
+                            .forDevice(data().deviceId())
+                            .makePermanent()
+                            .withSelector(selector)
+                            .withTreatment(treatment)
+                            .withPriority(lookup.getRight())
+                            .withCookie(lookup.getLeft().value())
+                            .build();
+                    rules.add(fr);
+                }
+            }
+        }
+
+        return rules;
+    }
+}
