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;
+    }
+}
diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java
index 3dc94df..a67c2f6 100644
--- a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java
+++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java
@@ -17,7 +17,10 @@
 package org.onosproject.drivers.juniper;
 
 import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.commons.lang.StringUtils;
 import org.onlab.packet.ChassisId;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
 import org.onlab.packet.MacAddress;
 import org.onosproject.net.AnnotationKeys;
 import org.onosproject.net.ConnectPoint;
@@ -39,18 +42,23 @@
 import com.google.common.base.Strings;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import static org.onosproject.drivers.juniper.StaticRoute.DEFAULT_METRIC_STATIC_ROUTE;
+import static org.onosproject.drivers.juniper.StaticRoute.toFlowRulePriority;
 import static org.onosproject.net.Device.Type.ROUTER;
 import static org.onosproject.net.PortNumber.portNumber;
 import static org.slf4j.LoggerFactory.getLogger;
 
 // Ref: Junos YANG:
 //   https://github.com/Juniper/yang
+
 /**
  * Utility class for Netconf XML for Juniper.
  * Tested with MX240 junos 14.2
@@ -96,6 +104,8 @@
     private static final Pattern ADD_PATTERN =
             Pattern.compile(REGEX_ADD, Pattern.DOTALL);
 
+    public static final String PROTOCOL_NAME = "protocol-name";
+
     private static final String JUNIPER = "JUNIPER";
     private static final String UNKNOWN = "UNKNOWN";
 
@@ -161,6 +171,80 @@
     }
 
     /**
+     * Helper method to commit a config.
+     *
+     * @return string contains the result of the commit
+     */
+    public static String commitBuilder() {
+        return RPC_TAG_NETCONF_BASE +
+                "<commit/>" + RPC_CLOSE_TAG;
+    }
+
+    /**
+     * Helper method to build the schema for returning to a previously
+     * committed configuration.
+     *
+     * @param versionToReturn Configuration to return to. The range of values is from 0 through 49.
+     *                        The most recently saved configuration is number 0,
+     *                        and the oldest saved configuration is number 49.
+     * @return string containing the XML schema
+     */
+    public static String rollbackBuilder(int versionToReturn) {
+        return RPC_TAG_NETCONF_BASE +
+                "<get-rollback-information>" +
+                "<rollback>" + versionToReturn + "</rollback>" +
+                "</get-rollback-information>" +
+                RPC_CLOSE_TAG;
+    }
+
+
+    /**
+     * Helper method to build an XML schema to configure a static route
+     * given a {@link StaticRoute}.
+     *
+     * @param staticRoute the static route to be configured
+     * @return string contains the result of the configuration
+     */
+    public static String routeAddBuilder(StaticRoute staticRoute) {
+        StringBuilder rpc = new StringBuilder("<configuration>\n");
+        rpc.append("<routing-options>\n");
+        rpc.append("<static>\n");
+        rpc.append("<route>\n");
+        rpc.append("<destination>" + staticRoute.ipv4Dst().toString() + "</destination>\n");
+        rpc.append("<next-hop>" + staticRoute.nextHop() + "</next-hop>\n");
+
+        if (staticRoute.getMetric() != DEFAULT_METRIC_STATIC_ROUTE) {
+            rpc.append("<metric>" + staticRoute.getMetric() + "</metric>");
+        }
+
+        rpc.append("</route>\n");
+        rpc.append("</static>\n");
+        rpc.append("</routing-options>\n");
+        rpc.append("</configuration>\n");
+
+        return rpc.toString();
+    }
+
+    /**
+     * Helper method to build a XML schema to delete a static route
+     * given a {@link StaticRoute}.
+     * @param staticRoute the static route to be deleted
+     * @return string contains the result of the configuratio
+     */
+    public static String routeDeleteBuilder(StaticRoute staticRoute) {
+        return "<configuration>\n" +
+        "<routing-options>\n" +
+        "<static>\n" +
+        "<route operation=\"delete\">\n" +
+        "<name>" + staticRoute.ipv4Dst().toString() + "</name>\n" +
+        "</route>\n" +
+        "</static>\n" +
+        "</routing-options>\n" +
+        "</configuration>\n";
+    }
+
+
+    /**
      * Parses device configuration and returns the device description.
      *
      * @param deviceId    the id of the device
@@ -458,4 +542,68 @@
             this.remotePortIndex = pIndex;
         }
     }
+
+    protected enum OperationType {
+        ADD,
+        REMOVE,
+    }
+
+    /**
+     * Parses {@literal route-information} tree.
+     * This implementation supports only static routes.
+     *
+     * @param cfg route-information
+     * @return a collection of static routes
+     */
+    public static Collection<StaticRoute> parseRoutingTable(HierarchicalConfiguration cfg) {
+
+        Collection<StaticRoute> staticRoutes = new HashSet<>();
+        HierarchicalConfiguration routeInfo =
+                cfg.configurationAt("route-information");
+        List<HierarchicalConfiguration> routeTables = routeInfo.configurationsAt("route-table");
+        for (HierarchicalConfiguration routeTable : routeTables) {
+            List<HierarchicalConfiguration> routes = routeTable.configurationsAt("rt");
+            for (HierarchicalConfiguration route : routes) {
+                if (route != null) {
+                    HierarchicalConfiguration rtEntry = route.configurationAt("rt-entry");
+                    if (rtEntry.getString(PROTOCOL_NAME) != null &&
+                            rtEntry.getString(PROTOCOL_NAME).contains("Static")) {
+                        parseStaticRoute(rtEntry,
+                                route.getString("rt-destination"),
+                                rtEntry.getString("metric"))
+                                .ifPresent(x -> staticRoutes.add(x));
+
+                    }
+                }
+            }
+        }
+        return staticRoutes;
+    }
+
+    /**
+     * Parse the {@literal rt-entry} for static routes.
+     *
+     * @param rtEntry     rt-entry filtered by {@literal protocol-name} equals to Static
+     * @param destination rt-destination
+     * @return optional of static route
+     */
+    private static Optional<StaticRoute> parseStaticRoute(HierarchicalConfiguration rtEntry,
+                                                          String destination, String metric) {
+
+        Ip4Prefix ipDst = Ip4Prefix.valueOf(destination);
+
+        HierarchicalConfiguration nextHop = rtEntry.configurationAt("nh");
+        String to = nextHop.getString("to");
+        if (StringUtils.isEmpty(to)) {
+            return Optional.empty();
+        }
+        Ip4Address nextHopIp = Ip4Address.valueOf(to);
+
+        if (metric == null) {
+            return Optional.of(new StaticRoute(ipDst, nextHopIp, false));
+        } else {
+            return Optional.of(new StaticRoute(ipDst, nextHopIp, false,
+                    toFlowRulePriority(Integer.parseInt(metric))));
+        }
+    }
 }
diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/StaticRoute.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/StaticRoute.java
new file mode 100644
index 0000000..f83d0bb
--- /dev/null
+++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/StaticRoute.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2017-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.juniper;
+
+import com.google.common.annotations.Beta;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.onosproject.net.intent.Intent.DEFAULT_INTENT_PRIORITY;
+
+
+/**
+ * Definition of a static route for the Juniper.
+ */
+@Beta
+public class StaticRoute {
+
+    /**
+     * Maximum metric value for the Juniper.
+     */
+    private static final int BEST_STATIC_METRIC = 1;
+
+    /**
+     * Max FlowRule priority that corresponds to the BEST_STATIC_METRIC of the Juniper.
+     * DEFAULT_INTENT_PRIORITY + DEFAULT_METRIC_STATIC_ROUTE - BEST_STATIC_METRIC
+     */
+    private static final int MAX_FLOWRULE_PRIORITY_ACCEPTED = 104;
+
+    /**
+     * Default static route metric.
+     */
+    public static final int DEFAULT_METRIC_STATIC_ROUTE = 5;
+
+    private final Ip4Prefix ipv4Dest;
+    private final Ip4Address nextHop;
+    private final int priority;
+    private final boolean localRoute;
+
+    public StaticRoute(Ip4Prefix ipv4Dest, Ip4Address nextHop, boolean localRoute, int priority) {
+        this.ipv4Dest = ipv4Dest;
+        this.nextHop = nextHop;
+        this.priority = priority;
+        this.localRoute = localRoute;
+    }
+
+    public StaticRoute(Ip4Prefix ipv4Dest, Ip4Address nextHop, boolean localRoute) {
+        this(ipv4Dest, nextHop, localRoute, DEFAULT_INTENT_PRIORITY);
+    }
+
+    public Ip4Prefix ipv4Dst() {
+        return ipv4Dest;
+    }
+
+    public Ip4Address nextHop() {
+        return nextHop;
+    }
+
+    /**
+     * Method to covert the priority into the Juniper metric.
+     * See https://goo.gl/ACo952.
+     * @return the metric for the Juniper
+     */
+    public int getMetric() {
+        if (priority > MAX_FLOWRULE_PRIORITY_ACCEPTED) {
+            return BEST_STATIC_METRIC;
+        }
+        return DEFAULT_INTENT_PRIORITY + DEFAULT_METRIC_STATIC_ROUTE - priority;
+    }
+
+    /**
+     * Method to convert the Juniper metric into a priority.
+     *
+     * @param metric the metric to be converted
+     * @return the priority
+     */
+    public static int toFlowRulePriority(int metric) {
+        return DEFAULT_INTENT_PRIORITY + DEFAULT_METRIC_STATIC_ROUTE - metric;
+    }
+
+    /**
+     * Directly attached routes are called local route. Such local routes are directly discovered by
+     * the router itself.
+     *
+     * @return true if it is a local route
+     */
+    public boolean isLocalRoute() {
+        return localRoute;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof StaticRoute) {
+            StaticRoute that = (StaticRoute) obj;
+            return Objects.equals(ipv4Dest, that.ipv4Dest) &&
+                    Objects.equals(nextHop, that.nextHop) &&
+                    Objects.equals(priority, that.priority) &&
+                    Objects.equals(localRoute, that.localRoute);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ipv4Dest, nextHop, priority, localRoute);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .omitNullValues()
+                .addValue(localRoute ? "Local route" : null)
+                .add("IP address destination", ipv4Dest)
+                .add("Next Hop IP address", nextHop)
+                .add("Priority", priority)
+                .toString();
+    }
+}
