diff --git a/gcc/config/s390/s390-builtin-types.def b/gcc/config/s390/s390-builtin-types.def
index 7aeea343126abe50dff7a11df1105b8a3763692a..398ea6eb60a1683fd58ad38d1ab7a57d8924d226 100644
--- a/gcc/config/s390/s390-builtin-types.def
+++ b/gcc/config/s390/s390-builtin-types.def
@@ -136,6 +136,7 @@ DEF_OPAQUE_VECTOR_TYPE (BT_OV4SI, BT_INT, 4)
 DEF_FN_TYPE_0 (BT_FN_INT, BT_INT)
 DEF_FN_TYPE_0 (BT_FN_UINT, BT_UINT)
 DEF_FN_TYPE_0 (BT_FN_VOID, BT_VOID)
+DEF_FN_TYPE_1 (BT_FN_INT128_INT128, BT_INT128, BT_INT128)
 DEF_FN_TYPE_1 (BT_FN_INT128_V2DI, BT_INT128, BT_V2DI)
 DEF_FN_TYPE_1 (BT_FN_INT_INT, BT_INT, BT_INT)
 DEF_FN_TYPE_1 (BT_FN_INT_VOIDPTR, BT_INT, BT_VOIDPTR)
diff --git a/gcc/config/s390/s390-builtins.def b/gcc/config/s390/s390-builtins.def
index 9c3334453b81af5e4ce926d0fcbefc92a39633e2..32ec2eb8a416f4ef292beb1c457c112133ed7984 100644
--- a/gcc/config/s390/s390-builtins.def
+++ b/gcc/config/s390/s390-builtins.def
@@ -1820,6 +1820,7 @@ OB_DEF_VAR (s390_vec_abs_s8,            s390_vlpb,          0,
 OB_DEF_VAR (s390_vec_abs_s16,           s390_vlph,          0,                  0,                  BT_OV_V8HI_V8HI)
 OB_DEF_VAR (s390_vec_abs_s32,           s390_vlpf,          0,                  0,                  BT_OV_V4SI_V4SI)
 OB_DEF_VAR (s390_vec_abs_s64,           s390_vlpg,          0,                  0,                  BT_OV_V2DI_V2DI)
+OB_DEF_VAR (s390_vec_abs_s128,          s390_vlpq,          0,                  0,                  BT_OV_V1TI_V1TI)    /* NOGEN */
 OB_DEF_VAR (s390_vec_abs_flt,           s390_vflpsb,        B_VXE,              0,                  BT_OV_V4SF_V4SF)
 OB_DEF_VAR (s390_vec_abs_dbl,           s390_vflpdb,        0,                  0,                  BT_OV_V2DF_V2DF)
 
@@ -1827,6 +1828,7 @@ B_DEF      (s390_vlpb,                  absv16qi2,          0,
 B_DEF      (s390_vlph,                  absv8hi2,           0,                  B_VX,               0,                  BT_FN_V8HI_V8HI)
 B_DEF      (s390_vlpf,                  absv4si2,           0,                  B_VX,               0,                  BT_FN_V4SI_V4SI)
 B_DEF      (s390_vlpg,                  absv2di2,           0,                  B_VX,               0,                  BT_FN_V2DI_V2DI)
+B_DEF      (s390_vlpq,                  absti2,             0,                  B_VX,               0,                  BT_FN_INT128_INT128)
 B_DEF      (s390_vflpsb,                absv4sf2,           0,                  B_VXE,              0,                  BT_FN_V4SF_V4SF)
 B_DEF      (s390_vflpdb,                absv2df2,           0,                  B_VX,               0,                  BT_FN_V2DF_V2DF)
 
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 57a9d20f7f7646ffaddcc8cb4ac9aed9e5051cc7..8824c4fbebdb9476ef09fa22ad555288fefda0db 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -1191,10 +1191,29 @@
   "vlc<bhfgq>\t%v0,%v1"
   [(set_attr "op_type" "VRR")])
 
-; vlpb, vlph, vlpf, vlpg
-(define_insn "abs<mode>2"
-  [(set (match_operand:VI         0 "register_operand" "=v")
-	(abs:VI (match_operand:VI 1 "register_operand"  "v")))]
+(define_expand "abs<mode>2"
+  [(set (match_operand:VIT          0 "register_operand" "=v")
+	(abs:VIT (match_operand:VIT 1 "register_operand"  "v")))]
+  "TARGET_VX"
+{
+  // Emulate via vec_sel (op1, -op1, op1 < 0)
+  if ((<MODE>mode == V1TImode || <MODE>mode == TImode) && !TARGET_VXE3)
+    {
+      rtx zero = gen_reg_rtx (<MODE>mode);
+      rtx neg_op1 = gen_reg_rtx (<MODE>mode);
+      rtx lt = gen_reg_rtx (<MODE>mode);
+      emit_move_insn (zero, GEN_INT (0));
+      emit_move_insn (neg_op1, gen_rtx_MINUS (<MODE>mode, zero, operands[1]));
+      s390_expand_vec_compare (lt, LT, operands[1], zero);
+      emit_insn (gen_vec_sel0<mode> (operands[0], operands[1], neg_op1, lt, GEN_INT (0)));
+      DONE;
+    }
+})
+
+; vlpb, vlph, vlpf, vlpg, vlpq
+(define_insn "*abs<mode>2"
+  [(set (match_operand:VIT_VXE3               0 "register_operand" "=v")
+	(abs:VIT_VXE3 (match_operand:VIT_VXE3 1 "register_operand"  "v")))]
   "TARGET_VX"
   "vlp<bhfgq>\t%v0,%v1"
   [(set_attr "op_type" "VRR")])
@@ -2430,7 +2449,7 @@
 })
 
 ; op0 = op3 == 0 ? op1 : op2
-(define_insn "*vec_sel0<mode>"
+(define_insn "vec_sel0<mode>"
   [(set (match_operand:VT 0 "register_operand" "=v")
 	(if_then_else:VT
 	 (eq (match_operand:<TOINTVEC> 3 "register_operand" "v")
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c b/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c
new file mode 100644
index 0000000000000000000000000000000000000000..8c1038a13d75617d533c2ceeb483dbee916bac55
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -mzarch -march=z13 -save-temps" } */
+/* { dg-require-effective-target int128 } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+/* { dg-final { scan-assembler-not {\tvlpq\t} } } */
+
+#include <assert.h>
+
+typedef __attribute__ ((vector_size (16))) signed long long v2di;
+typedef __attribute__ ((vector_size (16))) signed __int128 v1ti;
+
+/*
+** my_abs:
+**	vzero	%v[0-9]+
+**	vchlg	%v[0-9]+,%v[0-9]+,%v[0-9]+
+**	vceqg	%v[0-9]+,%v[0-9]+,%v[0-9]+
+**	vpdi	%v[0-9]+,%v[0-9]+,%v[0-9]+,4
+**	vchg	%v[0-9]+,%v[0-9]+,%v[0-9]+
+**	vn	%v[0-9]+,%v[0-9]+,%v[0-9]+
+**	vo	%v[0-9]+,%v[0-9]+,%v[0-9]+
+**	vrepg	%v[0-9]+,%v[0-9]+,1
+**	vsq	%v[0-9]+,%v[0-9]+,%v[0-9]+
+**	vsel	%v[0-9]+,%v[0-9]+,%v[0-9]+,%v[0-9]+
+**	br	%r14
+*/
+__attribute__ ((noipa)) v1ti
+my_abs (v1ti x)
+{
+  return __builtin_s390_vec_abs (x);
+}
+
+int
+main (void)
+{
+  v2di x;
+
+  x = (v2di){ -1, -42 };
+  x = (v2di) my_abs ((v1ti) x);
+  assert (x[0] == 0 && x[1] == 42);
+
+  x = (v2di){ 0, 42 };
+  x = (v2di) my_abs ((v1ti) x);
+  assert (x[0] == 0 && x[1] == 42);
+
+  return 0;
+}