diff --git a/routingtable/adjRIBOutAddPath/adj_rib_out_add_path.go b/routingtable/adjRIBOutAddPath/adj_rib_out_add_path.go
index 07b702db3360040de4c4d190a16fc4cabfdb2a38..2b4dff95575b2df72036642f40bd69cfedb4e5ab 100644
--- a/routingtable/adjRIBOutAddPath/adj_rib_out_add_path.go
+++ b/routingtable/adjRIBOutAddPath/adj_rib_out_add_path.go
@@ -12,16 +12,18 @@ import (
 // AdjRIBOutAddPath represents an Adjacency RIB Out with BGP add path
 type AdjRIBOutAddPath struct {
 	routingtable.ClientManager
-	rt       *routingtable.RoutingTable
-	neighbor *routingtable.Neighbor
-	mu       sync.RWMutex
+	rt            *routingtable.RoutingTable
+	neighbor      *routingtable.Neighbor
+	pathIDManager *pathIDManager
+	mu            sync.RWMutex
 }
 
 // New creates a new Adjacency RIB Out with BGP add path
 func New(neighbor *routingtable.Neighbor) *AdjRIBOutAddPath {
 	a := &AdjRIBOutAddPath{
-		rt:       routingtable.NewRoutingTable(),
-		neighbor: neighbor,
+		rt:            routingtable.NewRoutingTable(),
+		neighbor:      neighbor,
+		pathIDManager: newPathIDManager(),
 	}
 	a.ClientManager = routingtable.NewClientManager(a)
 	return a
@@ -41,8 +43,12 @@ func (a *AdjRIBOutAddPath) AddPath(pfx net.Prefix, p *route.Path) error {
 	a.mu.Lock()
 	defer a.mu.Unlock()
 
-	p.BGPPath.PathIdentifier = 7
+	pathID, err := a.pathIDManager.getNewID()
+	if err != nil {
+		return fmt.Errorf("Unable to get path ID: %v", err)
+	}
 
+	p.BGPPath.PathIdentifier = pathID
 	a.rt.AddPath(pfx, p)
 
 	for _, client := range a.ClientManager.Clients() {
@@ -66,6 +72,7 @@ func (a *AdjRIBOutAddPath) RemovePath(pfx net.Prefix, p *route.Path) bool {
 	}
 
 	a.rt.RemovePath(pfx, p)
+	a.pathIDManager.releaseID(p.BGPPath.PathIdentifier)
 	a.removePathFromClients(pfx, p)
 	return true
 }
diff --git a/routingtable/adjRIBOutAddPath/path_id_manager.go b/routingtable/adjRIBOutAddPath/path_id_manager.go
new file mode 100644
index 0000000000000000000000000000000000000000..0d79924941424b3cb7a772a6ca3df07ce914fb6e
--- /dev/null
+++ b/routingtable/adjRIBOutAddPath/path_id_manager.go
@@ -0,0 +1,47 @@
+package adjRIBOutAddPath
+
+import (
+	"fmt"
+)
+
+var maxUint32 = ^uint32(0)
+
+// pathIDManager manages BGP path identifiers for add-path. This is no thread safe (and doesn't need to be).
+type pathIDManager struct {
+	ids  map[uint32]struct{}
+	last uint32
+	used uint32
+}
+
+func newPathIDManager() *pathIDManager {
+	return &pathIDManager{
+		ids: make(map[uint32]struct{}),
+	}
+}
+
+func (fm *pathIDManager) getNewID() (uint32, error) {
+	if fm.used == maxUint32 {
+		return 0, fmt.Errorf("Out of path IDs")
+	}
+
+	fm.last++
+	for {
+		if _, exists := fm.ids[fm.last]; exists {
+			fm.last++
+			continue
+		}
+		break
+	}
+
+	ret := fm.last
+	fm.used++
+
+	return ret, nil
+}
+
+func (fm *pathIDManager) releaseID(id uint32) {
+	if _, exists := fm.ids[id]; exists {
+		delete(fm.ids, id)
+		fm.used--
+	}
+}
diff --git a/routingtable/adjRIBOutAddPath/path_id_manager_test.go b/routingtable/adjRIBOutAddPath/path_id_manager_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..c1cff4e6060b26075c99c957ae500fc74484f613
--- /dev/null
+++ b/routingtable/adjRIBOutAddPath/path_id_manager_test.go
@@ -0,0 +1,109 @@
+package adjRIBOutAddPath
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestGetNewID(t *testing.T) {
+	tests := []struct {
+		name     string
+		maxIDs   uint32
+		count    int
+		wantFail bool
+	}{
+		{
+			name:     "Out of path IDs",
+			maxIDs:   10,
+			count:    11,
+			wantFail: true,
+		},
+		{
+			name:     "Success",
+			maxIDs:   10,
+			count:    10,
+			wantFail: false,
+		},
+	}
+
+X:
+	for _, test := range tests {
+		maxUint32 = test.maxIDs
+		m := newPathIDManager()
+		for i := 0; i < test.count; i++ {
+			_, err := m.getNewID()
+			if err != nil {
+				if test.wantFail {
+					continue X
+				}
+
+				t.Errorf("Unexpected failure for test %q: %v", test.name, err)
+				continue X
+			}
+		}
+
+		if test.wantFail {
+			t.Errorf("Unexpected success for test %q", test.name)
+			continue
+		}
+	}
+}
+
+func TestReleaseID(t *testing.T) {
+	tests := []struct {
+		name     string
+		pm       *pathIDManager
+		release  uint32
+		expected *pathIDManager
+	}{
+		{
+			name: "Release existent",
+			pm: &pathIDManager{
+				ids: map[uint32]struct{}{
+					0: struct{}{},
+					1: struct{}{},
+					2: struct{}{},
+				},
+				last: 2,
+				used: 3,
+			},
+			release: 1,
+			expected: &pathIDManager{
+				ids: map[uint32]struct{}{
+					0: struct{}{},
+					2: struct{}{},
+				},
+				last: 2,
+				used: 2,
+			},
+		},
+		{
+			name: "Release non-existent",
+			pm: &pathIDManager{
+				ids: map[uint32]struct{}{
+					0: struct{}{},
+					1: struct{}{},
+					2: struct{}{},
+				},
+				last: 2,
+				used: 3,
+			},
+			release: 3,
+			expected: &pathIDManager{
+				ids: map[uint32]struct{}{
+					0: struct{}{},
+					1: struct{}{},
+					2: struct{}{},
+				},
+				last: 2,
+				used: 3,
+			},
+		},
+	}
+
+	for _, test := range tests {
+		test.pm.releaseID(test.release)
+		assert.Equalf(t, test.expected, test.pm, "%s", test.name)
+	}
+}