diff --git a/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/type/BmpPeerUpNotification.java b/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/type/BmpPeerUpNotification.java
new file mode 100644
index 0000000..cba9f04
--- /dev/null
+++ b/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/type/BmpPeerUpNotification.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright 2024-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.
+ */
+
+ /*
+      0                   1                   2                   3
+      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                 Local Address (16 bytes)                      |
+     ~                                                               ~
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |         Local Port            |        Remote Port            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                    Sent OPEN Message                          |
+     ~                                                               ~
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                  Received OPEN Message                        |
+     ~                                                               ~
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                 Information (variable)                        |
+     ~                                                               ~
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+package org.onosproject.bgpmonitoring.type;
+
+import org.jboss.netty.buffer.ChannelBuffers;
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.Deserializer;
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpMessage;
+import org.onosproject.bgpio.protocol.ver4.BgpMessageVer4;
+import org.onosproject.bgpio.types.BgpHeader;
+import org.onosproject.bgpmonitoring.PeerUpNotificationMessage;
+import org.onosproject.bgpmonitoring.BmpParseException;
+import org.onosproject.bgpmonitoring.PerPeer;
+
+import java.net.InetAddress;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.function.BiPredicate;
+import java.nio.ByteBuffer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * A message sent to indicate that a peering
+ * session has come up.  The message includes information regarding
+ * the data exchanged between the peers in their OPEN messages, as
+ * well as information about the peering TCP session itself.  In
+ * addition to being sent whenever a peer transitions to the
+ * Established state, a Peer Up Notification is sent for each peer in
+ * the Established state when the BMP session itself comes up.
+ * <p>
+ * Local Address: The local IP address associated with the peering
+ * TCP session.  It is 4 bytes long if an IPv4 address is carried in
+ * this field, as determined by the V flag (with the 12 most
+ * significant bytes zero-filled) and 16 bytes long if an IPv6
+ * address is carried in this field.
+ * <p>
+ * Local Port: The local port number associated with the peering TCP
+ * session, or 0 if no TCP session actually exists (see Section 8.2).
+ * <p>
+ * Remote Port: The remote port number associated with the peering
+ * TCP session, or 0 if no TCP session actually exists.
+ * <p>
+ * Sent OPEN Message: The full OPEN message transmitted by the
+ * monitored router to its peer.
+ * <p>
+ * Received OPEN Message: The full OPEN message received by the
+ * monitored router from its peer.
+ * Information: Information about the peer, using the Information TLV
+ * format.  Only the string type is defined in this
+ * context; it may be repeated.  Inclusion of the Information field
+ * is OPTIONAL.  Its presence or absence can be inferred by
+ * inspection of the Message Length in the common header.
+ */
+public final class BmpPeerUpNotification extends PeerUpNotificationMessage {
+
+    private static final Logger log = LoggerFactory.getLogger(BmpPeerUpNotification.class);
+
+    private PerPeer perPeer;
+
+    private InetAddress localAddress;
+
+    private int localPort;
+
+    private int remotePort;
+
+    private BgpMessage sentOpenMsg;
+
+    private BgpMessage receivedOpenMsg;
+
+    private byte[] information;
+
+
+    private BmpPeerUpNotification(Builder builder) {
+        this.perPeer = builder.perPeer;
+        this.localAddress = builder.localAddress;
+        this.localPort = builder.localPort;
+        this.remotePort = builder.remotePort;
+        this.sentOpenMsg = builder.sentOpenMsg;
+        this.receivedOpenMsg = builder.receivedOpenMsg;
+        this.information = builder.information;
+
+
+    }
+
+    /**
+     * Returns BMP Peer Header of BMP Message.
+     *
+     * @return BMP Peer Header of BMP Message
+     */
+    @Override
+    public PerPeer getPerPeer() {
+        return perPeer;
+    }
+
+    /**
+     * Returns local ip address.
+     *
+     * @return local ip address
+     */
+    public InetAddress getLocalAddress() {
+        return localAddress;
+    }
+
+    /**
+     * Returns local port number.
+     *
+     * @return local port number
+     */
+    public int getLocalPort() {
+        return localPort;
+    }
+
+    /**
+     * Returns remote port number.
+     *
+     * @return remote port number
+     */
+    public int getRemotePort() {
+        return remotePort;
+    }
+
+    /**
+     * Returns Bgp sent open message.
+     *
+     * @return Bgp sent open message
+     */
+    public BgpMessage getSentOpenMsg() {
+        return sentOpenMsg;
+    }
+
+    /**
+     * Returns Bgp received open message.
+     *
+     * @return Bgp received open message
+     */
+    public BgpMessage getReceivedOpenMsg() {
+        return receivedOpenMsg;
+    }
+
+    /**
+     * Returns BMP peer information.
+     *
+     * @return BMP peer information
+     */
+    public byte[] getInformation() {
+        return information;
+    }
+
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        BmpPeerUpNotification that = (BmpPeerUpNotification) o;
+        return localPort == that.localPort &&
+                remotePort == that.remotePort &&
+                Objects.equals(localAddress, that.localAddress) &&
+                Objects.equals(sentOpenMsg, that.sentOpenMsg) &&
+                Objects.equals(receivedOpenMsg, that.receivedOpenMsg) &&
+                Arrays.equals(information, that.information) &&
+                Objects.equals(perPeer, that.perPeer);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Objects.hash(localAddress, localPort, remotePort, sentOpenMsg,
+                receivedOpenMsg, perPeer);
+        result = 31 * result + Arrays.hashCode(information);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("perPeer", perPeer)
+                .add("localAddress", localAddress)
+                .add("localPort", localPort)
+                .add("remotePort", remotePort)
+                .add("sentOpenMsg", sentOpenMsg)
+                .add("receivedOpenMsg", receivedOpenMsg)
+                .add("information", Arrays.toString(information))
+                .toString();
+    }
+
+    /**
+     * Data deserializer function for BMP peer up notification message.
+     *
+     * @return data deserializer function
+     */
+    public static Deserializer<BmpPeerUpNotification> deserializer() {
+        return (data, offset, length) -> {
+            BiPredicate<ByteBuffer, Integer> isValidBuffer = (b, l)
+                    -> b.hasRemaining() && b.remaining() >= l;
+
+            ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
+            if (!isValidBuffer.test(bb, PEERUP_NOTIFICATION_HEADER_MIN_LENGTH +
+                    PerPeerPacket.PEER_HEADER_MIN_LENGTH)) {
+                throw new BmpParseException("Invalid bmp peer up notification message buffer size.");
+            }
+            byte[] perPeerBytes = new byte[PerPeerPacket.PEER_HEADER_MIN_LENGTH];
+            bb.get(perPeerBytes);
+
+            Builder builder = new Builder()
+                    .perPeer(PerPeerPacket.deserializer().deserialize(perPeerBytes,
+                            0, PerPeerPacket.PEER_HEADER_MIN_LENGTH));
+
+
+            if (builder.perPeer.isIpv6()) {
+                builder.localAddress(PerPeerPacket.toInetAddress(IPV6_ADDRS, bb));
+            } else {
+                bb.position(bb.position() + (IPV6_ADDRS - IPV4_ADDRS));
+                builder.localAddress(PerPeerPacket.toInetAddress(IPV4_ADDRS, bb));
+            }
+
+            builder.localPort(bb.getShort())
+                    .remotePort(bb.getShort());
+
+
+            if (bb.remaining() < (PADDING_BYTES + BGP_LENGTH_FIELD)) {
+                throw new BmpParseException("Invalid bmp peer up notification message buffer size.");
+            }
+
+            bb.position(bb.position() + PADDING_BYTES);
+            int msgLength = bb.getShort();
+            bb.position(bb.position() - (PADDING_BYTES + BGP_LENGTH_FIELD));
+
+            if (bb.remaining() < msgLength) {
+                throw new BmpParseException("Not enough readable bytes");
+            }
+            byte[] routeBytes = new byte[msgLength];
+            bb.get(routeBytes);
+            try {
+                builder.sentOpenMsg(BgpMessageVer4.READER.readFrom(ChannelBuffers.wrappedBuffer(routeBytes),
+                        new BgpHeader()));
+            } catch (BgpParseException ex) {
+                throw new BmpParseException(ex);
+            }
+
+            if (bb.remaining() < (PADDING_BYTES + BGP_LENGTH_FIELD)) {
+                throw new BmpParseException("Not enough readable bytes");
+            }
+
+            bb.position(bb.position() + PADDING_BYTES);
+            msgLength = bb.getShort();
+            bb.position(bb.position() - (PADDING_BYTES + BGP_LENGTH_FIELD));
+
+            if (bb.remaining() < msgLength) {
+                throw new BmpParseException("Not enough readable bytes");
+            }
+            routeBytes = new byte[msgLength];
+            bb.get(routeBytes);
+            try {
+                builder.receivedOpenMsg(BgpMessageVer4.READER.readFrom(ChannelBuffers.wrappedBuffer(routeBytes),
+                        new BgpHeader()));
+            } catch (BgpParseException ex) {
+                throw new BmpParseException(ex);
+            }
+
+            if (bb.remaining() > 0) {
+                byte[] information = new byte[bb.remaining()];
+                bb.get(information);
+                builder.information(information);
+
+            }
+
+            return builder.build();
+
+        };
+    }
+
+
+    /**
+     * Builder for BMP peer up notification message.
+     */
+    private static class Builder {
+
+
+        private PerPeer perPeer;
+
+        private InetAddress localAddress;
+
+        private int localPort;
+
+        private int remotePort;
+
+        private BgpMessage sentOpenMsg;
+
+        private BgpMessage receivedOpenMsg;
+
+        private byte[] information;
+
+        /**
+         * Setter bmp per peer header.
+         *
+         * @param perPeer bmp per peer header.
+         * @return this class builder.
+         */
+        public Builder perPeer(PerPeer perPeer) {
+            this.perPeer = perPeer;
+            return this;
+        }
+
+        /**
+         * Setter bgp local address.
+         *
+         * @param localAddress bgp local address.
+         * @return this class builder.
+         */
+        public Builder localAddress(InetAddress localAddress) {
+            this.localAddress = localAddress;
+            return this;
+        }
+
+
+        /**
+         * Setter bgp local port.
+         *
+         * @param localPort bgp local port.
+         * @return this class builder.
+         */
+        public Builder localPort(int localPort) {
+            this.localPort = localPort;
+            return this;
+        }
+
+        /**
+         * Setter bgp remote port.
+         *
+         * @param remotePort bgp remote port.
+         * @return this class builder.
+         */
+        public Builder remotePort(int remotePort) {
+            this.remotePort = remotePort;
+            return this;
+        }
+
+        /**
+         * Setter bgp send open message.
+         *
+         * @param sentOpenMsg bgp send open message.
+         * @return this class builder.
+         */
+        public Builder sentOpenMsg(BgpMessage sentOpenMsg) {
+            this.sentOpenMsg = sentOpenMsg;
+            return this;
+        }
+
+        /**
+         * Setter bgp receive open message.
+         *
+         * @param receivedOpenMsg bgp receive open message.
+         * @return this class builder.
+         */
+        public Builder receivedOpenMsg(BgpMessage receivedOpenMsg) {
+            this.receivedOpenMsg = receivedOpenMsg;
+            return this;
+        }
+
+        /**
+         * Setter bgp information message.
+         *
+         * @param information bgp information message.
+         * @return this class builder.
+         */
+        public Builder information(byte[] information) {
+            this.information = information;
+            return this;
+        }
+
+        /**
+         * Checks arguments for bmp peer up notification.
+         */
+        private void checkArguments() {
+            checkState(perPeer != null, "Invalid bmp per peer in peer up notification message.");
+            checkState(sentOpenMsg != null, "Invalid bgp send open message.");
+            checkState(receivedOpenMsg != null, "Invalid bgp receive open message.");
+        }
+
+        /**
+         * Builds BMP peer up notification message.
+         *
+         * @return BMP peer up notification message.
+         */
+        public BmpPeerUpNotification build() {
+            checkArguments();
+            return new BmpPeerUpNotification(this);
+        }
+    }
+}
