diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -280,6 +280,7 @@
     return R_PC;
   case R_RISCV_CALL:
   case R_RISCV_CALL_PLT:
+  case R_RISCV_PLT32:
     return R_PLT_PC;
   case R_RISCV_GOT_HI20:
     return R_GOT_PC;
@@ -473,6 +474,7 @@
     return;
   case R_RISCV_SET32:
   case R_RISCV_32_PCREL:
+  case R_RISCV_PLT32:
     write32le(loc, val);
     return;
 
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -517,6 +517,7 @@
   case R_RISCV_CALL_PLT:
   case R_RISCV_RVC_BRANCH:
   case R_RISCV_RVC_JUMP:
+  case R_RISCV_PLT32:
     return p;
   default:
     return 0;
diff --git a/lld/test/ELF/riscv-reloc-plt32.s b/lld/test/ELF/riscv-reloc-plt32.s
new file mode 100644
--- /dev/null
+++ b/lld/test/ELF/riscv-reloc-plt32.s
@@ -0,0 +1,21 @@
+// RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=riscv64 %S/Inputs/abs256.s -o %t256.o
+
+// RUN: ld.lld -z max-page-size=4096 %t.o %t256.o -o %t2
+// RUN: llvm-objdump -s --section=.data %t2 | FileCheck %s
+
+// CHECK: Contents of section .data:
+/// 12158: S = 0x100, A = 0, P = 0x12158
+///        S + A - P = 0xfffedfa8
+/// 1215c: S = 0x100, A = 1, P = 0x1215c
+///        S + A - P = 0xfffedfa5
+/// 12160: S = 0x100, A = -1, P = 0x12160
+///        S + A - P = 0xfffedf9f
+// CHECK-NEXT: 12158 a8dffeff a5dffeff 9fdffeff
+
+  .globl _start
+  _start:
+.data
+  .word foo@PLT - .
+  .word foo@PLT - . + 1
+  .word foo@PLT - . - 1
diff --git a/lld/test/ELF/riscv-undefined-weak.s b/lld/test/ELF/riscv-undefined-weak.s
--- a/lld/test/ELF/riscv-undefined-weak.s
+++ b/lld/test/ELF/riscv-undefined-weak.s
@@ -84,3 +84,6 @@
 
 # PC-NOT:      .plt:
 # PLT:         .plt:
+
+.word target@plt - .
+# RELOC:      0xC R_RISCV_PLT32 target 0x0
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
@@ -54,3 +54,4 @@
 ELF_RELOC(R_RISCV_SET32,             56)
 ELF_RELOC(R_RISCV_32_PCREL,          57)
 ELF_RELOC(R_RISCV_IRELATIVE,         58)
+ELF_RELOC(R_RISCV_PLT32,             59)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
@@ -13,6 +13,7 @@
 #include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCFixup.h"
 #include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCValue.h"
 #include "llvm/Support/ErrorHandling.h"
 
 using namespace llvm;
@@ -61,7 +62,9 @@
       return ELF::R_RISCV_NONE;
     case FK_Data_4:
     case FK_PCRel_4:
-      return ELF::R_RISCV_32_PCREL;
+      return Target.getAccessVariant() == MCSymbolRefExpr::VK_PLT
+                 ? ELF::R_RISCV_PLT32
+                 : ELF::R_RISCV_32_PCREL;
     case RISCV::fixup_riscv_pcrel_hi20:
       return ELF::R_RISCV_PCREL_HI20;
     case RISCV::fixup_riscv_pcrel_lo12_i:
diff --git a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
--- a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
@@ -18,6 +18,8 @@
                                           const TargetMachine &TM) {
   TargetLoweringObjectFileELF::Initialize(Ctx, TM);
 
+  PLTRelativeVariantKind = MCSymbolRefExpr::VK_PLT;
+
   SmallDataSection = getContext().getELFSection(
       ".sdata", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
   SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
diff --git a/llvm/test/MC/RISCV/elf-reloc-plt32.s b/llvm/test/MC/RISCV/elf-reloc-plt32.s
new file mode 100644
--- /dev/null
+++ b/llvm/test/MC/RISCV/elf-reloc-plt32.s
@@ -0,0 +1,10 @@
+// RUN: llvm-mc -triple=riscv64 -filetype=obj %s -o - | \
+// RUN:   llvm-readobj -r - | FileCheck %s
+
+  .section .data
+this:
+  .word extern_func@PLT - this + 4
+
+// CHECK:      Section ({{.*}}) .rela.data
+// CHECK-NEXT:   0x0 R_RISCV_PLT32 extern_func 0x4
+// CHECK-NEXT: }