diff --git a/docs/clmc-service.md b/docs/clmc-service.md
index 8f8c1ef30dfdedf5b39a4fe5e84c25a3ec3a30a0..7a435b73172a409445ff172ee171b7fbd1a8dfa6 100644
--- a/docs/clmc-service.md
+++ b/docs/clmc-service.md
@@ -573,6 +573,11 @@ with **/clmc-service** so that the nginx reverse proxy server (listening on port
         }
         ```
 
+* **PUT** ***/graph/network***
+
+    This API methods provides the same functionality as the *POST /graph/network* API endpoint with the only difference being
+    that the properties (e.g. latency) of any existing links between network nodes that already exist will be updated.
+
 * **DELETE** ***/graph/network***
 
     This API method instructs CLMC to delete the network topology from its graph database.
diff --git a/src/service/clmcservice/graphapi/tests.py b/src/service/clmcservice/graphapi/tests.py
index 7830b4338cd51ebb17dcd97f1d63eb2efffa100a..4a8bd585fd71a823043f0db6fbc3b00918f92783 100644
--- a/src/service/clmcservice/graphapi/tests.py
+++ b/src/service/clmcservice/graphapi/tests.py
@@ -30,7 +30,8 @@ from pyramid import testing
 from pyramid.httpexceptions import HTTPBadRequest, HTTPNotFound, HTTPInternalServerError
 from clmcservice.graphapi.views import GraphAPI
 from clmcservice.models import MonitoringProcess
-from clmcservice.graphapi.conftest import links, sdn_switches, ues, clusters
+from clmcservice.graphapi.conftest import links, sdn_switches, switches, ues, clusters
+from clmcservice.graphapi.utilities import delete_network_graph
 
 
 class TestGraphAPI(object):
@@ -494,22 +495,21 @@ class TestGraphAPI(object):
         mock_response3.status_code = 200
         mock_response3.json.return_value = links
         # we are doing two calls to the API, hence need to repeat the responses
-        http_get_mock.side_effect = [mock_response1, mock_response2, mock_response3, mock_response1, mock_response2, mock_response3]
+        http_get_mock.side_effect = [mock_response1, mock_response2, mock_response3] * 2
 
         # mock the behaviour of reading the clusters and ues mappping from files
         file_open_mock.return_value = MagicMock()  # use magic mock so that special methods (dunders) are auto generated
         # we are doing two calls to the API, hence need to repeat the results
-        json_load_mock.side_effect = [clusters, ues, clusters, ues]
+        json_load_mock.side_effect = [clusters, ues] * 2
 
         assert set([node["name"] for node in graph_db.nodes.match("Cluster")]) == set(), "Cluster nodes must not be created before the build request"
         assert set([node["name"] for node in graph_db.nodes.match("Switch")]) == set(), "Switch nodes must not be created before the build request"
         assert set([node["name"] for node in graph_db.nodes.match("UserEquipment")]) == set(), "UE nodes must not be created before the build request"
 
-        # sent request to build the network topology
+        # sent request to build the network topology through a POST request
         request = testing.DummyRequest()
         response = GraphAPI(request).build_network_topology()
         assert response == {"new_switches_count": 6, "new_clusters_count": 6, "new_ues_count": 3}
-
         assert set([node["name"] for node in graph_db.nodes.match("Cluster")]) == set(["DC" + str(i) for i in range(1, 7)]), "Cluster nodes must have been created"
         assert set([node["name"] for node in graph_db.nodes.match("Switch")]) == set(["127.0.0." + str(i) for i in range(1, 7)]), "Switch nodes must have been created"
         assert set([node["name"] for node in graph_db.nodes.match("UserEquipment")]) == set(["ue" + str(i) for i in (2, 3, 6)]), "UE nodes must have been created"
@@ -518,11 +518,85 @@ class TestGraphAPI(object):
         request = testing.DummyRequest()
         response = GraphAPI(request).build_network_topology()
         assert response == {"new_switches_count": 0, "new_clusters_count": 0, "new_ues_count": 0}
-
         assert set([node["name"] for node in graph_db.nodes.match("Cluster")]) == set(["DC" + str(i) for i in range(1, 7)])
         assert set([node["name"] for node in graph_db.nodes.match("Switch")]) == set(["127.0.0." + str(i) for i in range(1, 7)])
         assert set([node["name"] for node in graph_db.nodes.match("UserEquipment")]) == set(["ue" + str(i) for i in (2, 3, 6)])
 
+        # clean up
+        delete_network_graph(graph_db)
+
+    @patch('clmcservice.graphapi.views.load')
+    @patch('clmcservice.graphapi.views.open')
+    @patch('clmcservice.graphapi.views.get')
+    def test_build_and_update_network(self, http_get_mock, file_open_mock, json_load_mock, db_testing_data):
+        """
+        Tests the functionality to build and update the network graph.
+
+        :param http_get_mock: mocks the HTTP GET function
+        :param file_open_mock: mocks the open file function
+        :param json_load_mock: mocks the JSON load function
+        :param db_testing_data: fixture used to get a reference to the graph DB
+        """
+
+        from_timestamp, to_timestamp, graph_db = db_testing_data  # fixture, used to get reference to the graph DB
+
+        # mock the responses from the sdn controller - 3 GET requests are executed, so we need 3 responses
+        mock_response1 = Mock()
+        mock_response1.status_code = 200
+        mock_response1.json.return_value = sdn_switches
+        mock_response2 = Mock()
+        mock_response2.status_code = 200
+        mock_response2.json.return_value = links
+        mock_response3 = Mock()
+        mock_response3.status_code = 200
+        mock_response3.json.return_value = links
+        # we are doing two calls to the API, hence need to repeat the responses
+        http_get_mock.side_effect = [mock_response1, mock_response2, mock_response3] * 2
+
+        # mock the behaviour of reading the clusters and ues mappping from files
+        file_open_mock.return_value = MagicMock()  # use magic mock so that special methods (dunders) are auto generated
+        # we are doing two calls to the API, hence need to repeat the results
+        json_load_mock.side_effect = [clusters, ues] * 2
+
+        # sent request to build the network topology through a PUT request
+        request = testing.DummyRequest()
+        response = GraphAPI(request).build_and_update_network_topology()
+        assert response == {"new_switches_count": 6, "new_clusters_count": 6, "new_ues_count": 3}
+        assert set([node["name"] for node in graph_db.nodes.match("Cluster")]) == set(["DC" + str(i) for i in range(1, 7)]), "Cluster nodes must have been created"
+        assert set([node["name"] for node in graph_db.nodes.match("Switch")]) == set(["127.0.0." + str(i) for i in range(1, 7)]), "Switch nodes must have been created"
+        assert set([node["name"] for node in graph_db.nodes.match("UserEquipment")]) == set(["ue" + str(i) for i in (2, 3, 6)]), "UE nodes must have been created"
+
+        # fetch the first network link as test link
+        test_link = links[0]
+        test_link_source = switches[test_link["src-switch"]]
+        test_link_destination = switches[test_link["dst-switch"]]
+        test_link_source_node = graph_db.nodes.match("Switch", name=test_link_source).first()
+        test_link_destination_node = graph_db.nodes.match("Switch", name=test_link_destination).first()
+        # assert the nodes exist
+        assert test_link_source_node is not None
+        assert test_link_destination_node is not None
+
+        # confirm the latency value of the edge
+        old_latency = test_link["latency"] / 1000  # convert to seconds
+        test_link_edge = graph_db.relationships.match(nodes=(test_link_source_node, test_link_destination_node), r_type="linkedTo").first()
+        # assert the edge exists
+        assert test_link_edge is not None
+        assert test_link_edge["latency"] == old_latency, "Edge was not created with the correct latency value"
+
+        # update the test link in the SDN controller mock data with a new latency
+        new_latency = 5 * old_latency
+        test_link["latency"] = new_latency * 1000  # convert to milliseconds
+
+        # send the same request again and ensure that the latency of the network edge is updated
+        request = testing.DummyRequest()
+        GraphAPI(request).build_and_update_network_topology()
+
+        graph_db.pull(test_link_edge)
+        assert test_link_edge["latency"] == new_latency, "Edge was not updated with the correct latency value"
+
+        # clean up
+        delete_network_graph(graph_db)
+
     def test_delete_network(self, graph_network_topology, db_testing_data):
         """
         Tests the delete network graph functionality.
diff --git a/src/service/clmcservice/graphapi/utilities.py b/src/service/clmcservice/graphapi/utilities.py
index 9d8dd6808a5fc16440d65bb128fa6da17fe39f51..df339df1bc8e164e1a45e7262293da7946d138d3 100644
--- a/src/service/clmcservice/graphapi/utilities.py
+++ b/src/service/clmcservice/graphapi/utilities.py
@@ -350,7 +350,7 @@ def delete_temporal_subgraph(graph, subgraph_id):
     return nodes_matched
 
 
-def build_network_graph(graph, switches, links, clusters, ues):
+def build_network_graph(graph, switches, links, clusters, ues, update_existing_links=True):
     """
     A function used to build the network topology in the neo4j graph given the collection of switches, links and clusters.
 
@@ -359,6 +359,7 @@ def build_network_graph(graph, switches, links, clusters, ues):
     :param links: a collection of all switch-to-switch links in the network topology - JSON format, list of objects, each object must have "src-switch", "dst-switch" and "latency" as keys
     :param clusters: a collection of all clusters and the IP address of the service router that they are connected to - mapping between an IP address of a service router and a cluster identifier
     :param ues: a collection of all ues and the IP address of the service router that they are connected to - mapping between an IP address of a servicer router and a ue identifier
+    :param update_existing_links: (defaults to True) a flag to indicate if existing network edges must be updated with the latest latencies
     """
 
     new_switches_count = 0
@@ -391,7 +392,7 @@ def build_network_graph(graph, switches, links, clusters, ues):
 
         # create the link between the two nodes
         edge = find_or_create_edge(graph, "linkedTo", from_node, to_node, latency=latency)
-        if edge["latency"] != latency:
+        if update_existing_links and edge["latency"] != latency:
             log.info("Updating latency for edge {0}, old latency {1}, new latency {2}".format(edge, edge["latency"], latency))
             edge["latency"] = latency  # make sure that the latency is updated if the edge already existed
             graph.push(edge)  # update the relationship in the DB
diff --git a/src/service/clmcservice/graphapi/views.py b/src/service/clmcservice/graphapi/views.py
index e89f32e9376f2b979116f86f8e1f8ca1f21949cd..f7f251582d1dee5c3b82581bd4c235af6fd6bf8f 100644
--- a/src/service/clmcservice/graphapi/views.py
+++ b/src/service/clmcservice/graphapi/views.py
@@ -255,11 +255,32 @@ class GraphAPI(object):
     @view_config(route_name='graph_network_topology', request_method='POST')
     def build_network_topology(self):
         """
-        An API endpoint to build/update the network topology in the neo4j graph.
+        An API endpoint to build the network topology in the neo4j graph, however, without updating the latency of existing edges.
 
         :return: A JSON response with the number of switches, clusters and ues that were built.
         """
 
+        return self._build_network_topology(update_existing_links=False)
+
+    @view_config(route_name='graph_network_topology', request_method='PUT')
+    def build_and_update_network_topology(self):
+        """
+        An API endpoint to build the network topology in the neo4j graph and also update the latency of existing edges.
+
+        :return: A JSON response with the number of switches, clusters and ues that were built.
+        """
+
+        return self._build_network_topology(update_existing_links=True)
+
+    def _build_network_topology(self, update_existing_links):
+        """
+        A utility method used to build the network graph topology with the option of updating existing links.
+
+        :param update_existing_links: a flag to be set to True if existing network links need to be updated
+
+        :return: A dictionary with the number of switches, clusters and ues that were created.
+        """
+
         graph = self.get_graph_reference()
 
         sdn_controller_ip = self.request.registry.settings['sdn_controller_ip']
@@ -307,8 +328,8 @@ class GraphAPI(object):
             ues = {}
 
         # build the network graph and retrieve the number of switch nodes and cluster nodes that were created
-        tmp_switch_count, tmp_clusters_count, tmp_ues_count = build_network_graph(graph, switches, external_links, clusters, ues)
-        switch_count, clusters_count, ues_count = build_network_graph(graph, switches, local_links, clusters, ues)
+        tmp_switch_count, tmp_clusters_count, tmp_ues_count = build_network_graph(graph, switches, external_links, clusters, ues, update_existing_links=update_existing_links)
+        switch_count, clusters_count, ues_count = build_network_graph(graph, switches, local_links, clusters, ues, update_existing_links=update_existing_links)
         switch_count += tmp_switch_count
         clusters_count += tmp_clusters_count
         ues_count += tmp_ues_count