diff --git a/xos/synchronizer/steps/sync_routes.py b/xos/synchronizer/steps/sync_routes.py
new file mode 100644
index 0000000..5086933
--- /dev/null
+++ b/xos/synchronizer/steps/sync_routes.py
@@ -0,0 +1,83 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import requests
+from requests.auth import HTTPBasicAuth
+from synchronizers.new_base.syncstep import SyncStep, DeferredException
+from synchronizers.new_base.modelaccessor import VRouterStaticRoute
+
+from helpers import Helpers
+from multistructlog import create_logger
+from xosconfig import Config
+
+log = create_logger(Config().get('logging'))
+
+class SyncRoutes(SyncStep):
+    provides = [VRouterStaticRoute]
+    observes = VRouterStaticRoute
+
+    # Get fabric service info
+    def get_onos_fabric_service(self, model):
+        vrouter_service = model.vrouter.owner
+        fabric_service = vrouter_service.subscriber_services[0]
+        onos_fabric_service = fabric_service.subscriber_services[0]
+
+        return onos_fabric_service
+
+    def sync_record(self, model):
+        onos_fabric_service = self.get_onos_fabric_service(model)
+
+        onos = Helpers.get_onos_info(onos_fabric_service.leaf_model)
+        onos_basic_auth = HTTPBasicAuth(onos['user'], onos['pass'])
+
+        data = {
+          "prefix": model.prefix,
+          "nextHop": model.next_hop
+        }
+
+        url = '%s:%s/onos/routeservice/routes' % (onos['url'], onos['port'])
+        request = requests.post(url, json=data, auth=onos_basic_auth)
+
+        if request.status_code != 204:
+            log.error("Request failed", response=request.text)
+            raise Exception("Failed to add static route %s via %s in ONOS" % (model.prefix, model.next_hop))
+        else:
+            try:
+                print request.json()
+            except Exception:
+                print request.text
+
+    def delete_record(self, model):
+        onos_fabric_service = self.get_onos_fabric_service(model)
+
+        onos = Helpers.get_onos_info(onos_fabric_service.leaf_model)
+        onos_basic_auth = HTTPBasicAuth(onos['user'], onos['pass'])
+
+        data = {
+          "prefix": model.prefix,
+          "nextHop": model.next_hop
+        }
+
+        url = '%s:%s/onos/routeservice/routes' % (onos['url'], onos['port'])
+        request = requests.delete(url, json=data, auth=onos_basic_auth)
+
+        if request.status_code != 204:
+            log.error("Request failed", response=request.text)
+            raise Exception("Failed to delete static route %s via %s in ONOS" % (model.prefix, model.next_hop))
+        else:
+            try:
+                print request.json()
+            except Exception:
+                print request.text
