diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/FlowRuleJuniperImpl.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/FlowRuleJuniperImpl.java
new file mode 100644
index 0000000..ae9d7e9
--- /dev/null
+++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/FlowRuleJuniperImpl.java
@@ -0,0 +1,425 @@
+/*
+ * Copyright 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.juniper;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Strings;
+import org.apache.commons.lang.StringUtils;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+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.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleProgrammable;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.juniper.JuniperUtils.OperationType;
+import static org.onosproject.drivers.juniper.JuniperUtils.OperationType.ADD;
+import static org.onosproject.drivers.juniper.JuniperUtils.OperationType.REMOVE;
+import static org.onosproject.drivers.juniper.JuniperUtils.commitBuilder;
+import static org.onosproject.drivers.juniper.JuniperUtils.rollbackBuilder;
+import static org.onosproject.drivers.juniper.JuniperUtils.routeAddBuilder;
+import static org.onosproject.drivers.juniper.JuniperUtils.routeDeleteBuilder;
+import static org.onosproject.drivers.utilities.XmlConfigParser.loadXmlString;
+import static org.onosproject.net.flow.FlowEntry.FlowEntryState.PENDING_REMOVE;
+import static org.onosproject.net.flow.FlowEntry.FlowEntryState.REMOVED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Conversion of FlowRules into static routes and retrieve of installed
+ * static routes as FlowRules.
+ * The selector of the FlowRule must contains the IPv4 address
+ * {@link org.onosproject.net.flow.TrafficSelector.Builder#matchIPDst(org.onlab.packet.IpPrefix)}
+ * of the host to connect and the treatment must include an
+ * output port {@link org.onosproject.net.flow.TrafficTreatment.Builder#setOutput(PortNumber)}
+ * All other instructions in the selector and treatment are ignored.
+ * <p>
+ * This implementation requires an IP adjacency
+ * (e.g., IP link discovered by {@link LinkDiscoveryJuniperImpl}) between the routers
+ * to find the next hop IP address.
+ */
+@Beta
+public class FlowRuleJuniperImpl extends AbstractHandlerBehaviour
+        implements FlowRuleProgrammable {
+
+    private static final String OK = "<ok/>";
+    public static final String IP_STRING = "ip";
+    private final org.slf4j.Logger log = getLogger(getClass());
+
+    @Override
+    public Collection<FlowEntry> getFlowEntries() {
+
+        DeviceId devId = checkNotNull(this.data().deviceId());
+        NetconfController controller = checkNotNull(handler().get(NetconfController.class));
+        NetconfSession session = controller.getDevicesMap().get(devId).getSession();
+        if (session == null) {
+            log.warn("Device {} is not registered in netconf", devId);
+            return Collections.EMPTY_LIST;
+        }
+
+        //Installed static routes
+        String reply;
+        try {
+            reply = session.get(routingTableBuilder());
+        } catch (IOException e) {
+            throw new RuntimeException(new NetconfException("Failed to retrieve configuration.",
+                    e));
+        }
+        Collection<StaticRoute> devicesStaticRoutes =
+                JuniperUtils.parseRoutingTable(loadXmlString(reply));
+
+        //Expected FlowEntries installed
+        FlowRuleService flowRuleService = this.handler().get(FlowRuleService.class);
+        Iterable<FlowEntry> flowEntries = flowRuleService.getFlowEntries(devId);
+
+        Collection<FlowEntry> installedRules = new HashSet<>();
+        flowEntries.forEach(flowEntry -> {
+            Optional<IPCriterion> ipCriterion = getIpCriterion(flowEntry);
+            if (!ipCriterion.isPresent()) {
+                return;
+            }
+
+            Optional<OutputInstruction> output = getOutput(flowEntry);
+            if (!output.isPresent()) {
+                return;
+            }
+            //convert FlowRule into static route
+            getStaticRoute(devId, ipCriterion.get(), output.get(), flowEntry.priority()).ifPresent(staticRoute -> {
+                //Two type of FlowRules:
+                //1. FlowRules to forward to a remote subnet: they are translated into static route
+                // configuration. So a removal request will be processed.
+                //2. FlowRules to forward on a subnet directly attached to the router (Generally speaking called local):
+                // those routes do not require any configuration because the router is already able to forward on
+                // directly attached subnet. In this case, when the driver receive the request to remove,
+                // it will report as removed.
+
+                if (staticRoute.isLocalRoute()) {
+                    //if the FlowRule is in PENDING_REMOVE or REMOVED, it is not reported.
+                    if (flowEntry.state() == PENDING_REMOVE || flowEntry.state() == REMOVED) {
+                        devicesStaticRoutes.remove(staticRoute);
+                    } else {
+                        //FlowRule is reported installed
+                        installedRules.add(flowEntry);
+                        devicesStaticRoutes.remove(staticRoute);
+                    }
+
+                } else {
+                    //if the route is found in the device, the FlowRule is reported installed.
+                    if (devicesStaticRoutes.contains(staticRoute)) {
+                        installedRules.add(flowEntry);
+                        devicesStaticRoutes.remove(staticRoute);
+                    }
+                }
+            });
+        });
+
+        if (!devicesStaticRoutes.isEmpty()) {
+            log.info("Found static routes on device {} not installed by ONOS: {}",
+                    devId, devicesStaticRoutes);
+//            FIXME: enable configuration to purge already installed flows.
+//            It cannot be allowed by default because it may remove needed management routes
+//            log.warn("Removing from device {} the FlowEntries not expected {}", deviceId, devicesStaticRoutes);
+//            devicesStaticRoutes.forEach(staticRoute -> editRoute(session, REMOVE, staticRoute));
+        }
+        return installedRules;
+    }
+
+    @Override
+    public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
+        return manageRules(rules, ADD);
+    }
+
+    @Override
+    public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
+        return manageRules(rules, REMOVE);
+    }
+
+    private Collection<FlowRule> manageRules(Collection<FlowRule> rules, OperationType type) {
+
+        DeviceId deviceId = this.data().deviceId();
+
+        log.debug("{} flow entries to NETCONF device {}", type, deviceId);
+        NetconfController controller = checkNotNull(handler()
+                .get(NetconfController.class));
+        NetconfSession session = controller.getDevicesMap().get(deviceId)
+                .getSession();
+        Collection<FlowRule> managedRules = new HashSet<>();
+
+        for (FlowRule flowRule : rules) {
+
+            Optional<IPCriterion> ipCriterion = getIpCriterion(flowRule);
+            if (!ipCriterion.isPresent()) {
+                log.error("Currently not supported: IPv4 destination match must be used");
+                continue;
+            }
+
+            Optional<OutputInstruction> output = getOutput(flowRule);
+            if (!output.isPresent()) {
+                log.error("Currently not supported: the output action is needed");
+                continue;
+            }
+
+            getStaticRoute(deviceId, ipCriterion.get(), output.get(), flowRule.priority()).ifPresent(
+                    staticRoute -> {
+                        //If the static route is not local, the driver tries to install
+                        if (!staticRoute.isLocalRoute()) {
+                            //Only if the installation is successful, the driver report the
+                            // FlowRule as installed.
+                            if (editRoute(session, type, staticRoute)) {
+                                managedRules.add(flowRule);
+                            }
+                            //If static route are local, they are not installed
+                            // because are not required. Directly connected routes
+                            //are automatically forwarded.
+                        } else {
+                            managedRules.add(flowRule);
+                        }
+                    }
+            );
+        }
+        return rules;
+    }
+
+    private boolean editRoute(NetconfSession session, OperationType type,
+                              StaticRoute staticRoute) {
+        try {
+            boolean reply = false;
+            if (type == ADD) {
+                reply = session
+                        .editConfig(DatastoreId.CANDIDATE, "merge",
+                                routeAddBuilder(staticRoute));
+            } else if (type == REMOVE) {
+                reply = session
+                        .editConfig(DatastoreId.CANDIDATE, "none", routeDeleteBuilder(staticRoute));
+            }
+            if (reply && commit()) {
+                return true;
+            } else {
+                if (!rollback()) {
+                    log.error("Something went wrong in the configuration and impossible to rollback");
+                } else {
+                    log.error("Something went wrong in the configuration: a static route has not been {} {}",
+                            type == ADD ? "added" : "removed", staticRoute);
+                }
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(new NetconfException("Failed to retrieve configuration.",
+                    e));
+        }
+        return false;
+    }
+
+    /**
+     * Helper method to convert FlowRule into an abstraction of static route
+     * {@link StaticRoute}.
+     *
+     * @param devId    the device id
+     * @param criteria the IP destination criteria
+     * @param output   the output instruction
+     * @return optional of Static Route
+     */
+    private Optional<StaticRoute> getStaticRoute(DeviceId devId,
+                                                 IPCriterion criteria,
+                                                 OutputInstruction output,
+                                                 int priority) {
+
+        DeviceService deviceService = this.handler().get(DeviceService.class);
+        Collection<Port> ports = deviceService.getPorts(devId);
+        Optional<Port> port = ports.stream().filter(x -> x.number().equals(output.port())).findAny();
+        if (!port.isPresent()) {
+            log.error("The port {} does not exist in the device",
+                    output.port());
+            return Optional.empty();
+        }
+
+        //Find if the route refers to a local interface.
+        Optional<Port> local = deviceService.getPorts(devId).stream().filter(this::isIp)
+                .filter(p -> criteria.ip().getIp4Prefix().contains(
+                        Ip4Address.valueOf(p.annotations().value(IP_STRING)))).findAny();
+
+        if (local.isPresent()) {
+            return Optional.of(new StaticRoute(criteria.ip().getIp4Prefix(),
+                    criteria.ip().getIp4Prefix().address(), true, priority));
+        }
+
+        Optional<Ip4Address> nextHop = findIpDst(devId, port.get());
+        if (nextHop.isPresent()) {
+            return Optional.of(
+                    new StaticRoute(criteria.ip().getIp4Prefix(), nextHop.get(), false, priority));
+        } else {
+            log.error("The destination interface has not an IP {}", port.get());
+            return Optional.empty();
+        }
+
+    }
+
+    /**
+     * Helper method to get the IP destination criterion given a flow rule.
+     *
+     * @param flowRule the flow rule
+     * @return optional of IP destination criterion
+     */
+    private Optional<IPCriterion> getIpCriterion(FlowRule flowRule) {
+
+        Criterion ip = flowRule.selector().getCriterion(Criterion.Type.IPV4_DST);
+        return Optional.ofNullable((IPCriterion) ip);
+    }
+
+    /**
+     * Helper method to get the output instruction given a flow rule.
+     *
+     * @param flowRule the flow rule
+     * @return the output instruction
+     */
+    private Optional<OutputInstruction> getOutput(FlowRule flowRule) {
+        Optional<OutputInstruction> output = flowRule
+                .treatment().allInstructions().stream()
+                .filter(instruction -> instruction
+                        .type() == Instruction.Type.OUTPUT)
+                .map(x -> (OutputInstruction) x).findFirst();
+        return output;
+    }
+
+    private String routingTableBuilder() {
+        StringBuilder rpc = new StringBuilder("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">");
+        rpc.append("<get-route-information/>");
+        rpc.append("</rpc>");
+        return rpc.toString();
+    }
+
+    private boolean commit() {
+        NetconfController controller = checkNotNull(handler()
+                .get(NetconfController.class));
+        NetconfSession session = controller.getDevicesMap()
+                .get(handler().data().deviceId()).getSession();
+
+        String replay;
+        try {
+            replay = session.get(commitBuilder());
+        } catch (IOException e) {
+            throw new RuntimeException(new NetconfException("Failed to retrieve configuration.",
+                    e));
+        }
+
+        if (replay != null && replay.indexOf(OK) >= 0) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean rollback() {
+        NetconfController controller = checkNotNull(handler()
+                .get(NetconfController.class));
+        NetconfSession session = controller.getDevicesMap()
+                .get(handler().data().deviceId()).getSession();
+
+        String replay;
+        try {
+            replay = session.get(rollbackBuilder(0));
+        } catch (IOException e) {
+            throw new RuntimeException(new NetconfException("Failed to retrieve configuration.",
+                    e));
+        }
+
+        if (replay != null && replay.indexOf(OK) >= 0) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Helper method to find the next hop IP address.
+     * The logic is to check if the destination ports have an IP address
+     * by checking the logical interface (e.g., for port physical ge-2/0/1,
+     * a logical interface may be ge-2/0/1.0
+     *
+     * @param deviceId the device id of the flow rule to be installed
+     * @param port     output port of the flow rule treatment
+     * @return optional IPv4 address of a next hop
+     */
+    private Optional<Ip4Address> findIpDst(DeviceId deviceId, Port port) {
+        LinkService linkService = this.handler().get(LinkService.class);
+        Set<Link> links = linkService.getEgressLinks(new ConnectPoint(deviceId, port.number()));
+        DeviceService deviceService = this.handler().get(DeviceService.class);
+        //Using only links with adjacency discovered by the LLDP protocol (see LinkDiscoveryJuniperImpl)
+        Map<DeviceId, Port> dstPorts = links.stream().filter(l ->
+                IP_STRING.toUpperCase().equals(l.annotations().value("layer")))
+                .collect(Collectors.toMap(
+                        l -> l.dst().deviceId(),
+                        l -> deviceService.getPort(l.dst().deviceId(), l.dst().port())));
+        for (Map.Entry<DeviceId, Port> entry : dstPorts.entrySet()) {
+            String portName = entry.getValue().annotations().value(AnnotationKeys.PORT_NAME);
+
+            Optional<Port> childPort = deviceService.getPorts(entry.getKey()).stream()
+                    .filter(p -> Strings.nullToEmpty(
+                            p.annotations().value(AnnotationKeys.PORT_NAME)).contains(portName.trim()))
+                    .filter(p -> isIp(p))
+                    .findAny();
+            if (childPort.isPresent()) {
+                return Optional.ofNullable(Ip4Address.valueOf(childPort.get().annotations().value("ip")));
+            }
+        }
+
+        return Optional.empty();
+    }
+
+    /**
+     * Helper method to find if an interface has an IP address.
+     * It will check the annotations of the port.
+     *
+     * @param port the port
+     * @return true if the IP address is present. Otherwise false.
+     */
+    private boolean isIp(Port port) {
+        String ip4 = port.annotations().value(IP_STRING);
+        if (StringUtils.isEmpty(ip4)) {
+            return false;
+        }
+        try {
+
+            Ip4Address.valueOf(port.annotations().value(IP_STRING));
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+        return true;
+    }
+}
